* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <stdlib.h>
#include <glib/gstdio.h>
#include <glib-object.h>
#include <math.h>
/* Map image buffer */
GdkPixmap *buffer;
+#ifdef WITH_CAIRO
+ cairo_t *ct;
+#endif
+
PangoContext *context;
PangoLayout *layout;
PangoFontDescription *fontdesc;
GdkGLConfig* gl_config;
#endif
+ GdkGC *gc_mark;
+ GdkGC *gc_velvec;
+
gint mark_x1;
gint mark_x2;
gint mark_y1;
gint mark_y2;
- gint mark_minx;
- gint mark_miny;
- gint mark_width;
- gint mark_height;
+ GdkRectangle mark_rect;
guint buf_width_tiles;
guint buf_height_tiles;
#define unit2y(unit) (unit2pixel(unit) - tile2pixel(priv->base_tiley) - priv->offsety)
#define y2unit(y) (pixel2unit(y + priv->offsety) + tile2unit(priv->base_tiley))
-#define leadx2unit (location->unitx + (priv->lead_ratio) * pixel2unit(priv->vel_offsetx))
-#define leady2unit (location->unity + (0.6f*priv->lead_ratio) * pixel2unit(priv->vel_offsety))
+#define leadx2unit (priv->location.unitx + (priv->lead_ratio) * pixel2unit(priv->vel_offsetx))
+#define leady2unit (priv->location.unity + (0.6f*priv->lead_ratio) * pixel2unit(priv->vel_offsety))
#define GTK_MAP_TILE_SIZE_PIXELS (256)
#define GTK_MAP_TILE_SIZE_P2 (8)
-#define GTK_MAP_WORLD_SIZE_UNITS(max_zoom) (2 << (max_zoom + GTK_MAP_TILE_SIZE_P2))
+
+/* #define GTK_MAP_WORLD_SIZE_UNITS(max_zoom) (2 << (max_zoom + GTK_MAP_TILE_SIZE_P2)) */
+
+#define GTK_MAP_WORLD_SIZE_UNITS (1<<31)
/* Pans are done two "grids" at a time, or 64 pixels. */
#define GTK_MAP_PAN_UNITS (grid2unit(2))
#define GTK_MAP_MACRO_RECALC_CENTER(center_unitx, center_unity) { \
switch(priv->center_mode) { \
case CENTER_LEAD: \
- priv->center.unitx = leadx2unit; \
- priv->center.unity = leady2unit; \
+ priv->center.unitx = priv->leadx2unit; \
+ priv->center.unity = priv->leady2unit; \
break; \
case CENTER_LATLON: \
priv->center.unitx = priv->location.unitx; \
} \
};
-#define GTK_MAP_RECALC_OFFSET(center) { \
+#define GTK_MAP_MACRO_RECALC_OFFSET(center) { \
priv->offsetx = grid2pixel(unit2grid(center.unitx) - priv->screen_grids_halfwidth - tile2grid(priv->base_tilex)); \
priv->offsety = grid2pixel(unit2grid(center.unity) - priv->screen_grids_halfheight - tile2grid(priv->base_tiley)); \
}
-#define GTK_MAP_RECALC_FOCUS_BASE(sens) { \
- priv->focus.unitx = x2unit(priv->screen_width_pixels * sens / 20); \
- priv->focus.unity = y2unit(priv->screen_height_pixels * sens / 20); \
+#define GTK_MAP_MACRO_RECALC_FOCUS_BASE { \
+ priv->focus.unitx = x2unit(priv->screen_width_pixels * priv->center_ratio / 20); \
+ priv->focus.unity = y2unit(priv->screen_height_pixels * priv->center_ratio / 20); \
+}
+
+#define GTK_MAP_MACRO_RECALC_FOCUS_SIZE { \
+ priv->focus_unitwidth = pixel2unit((10 - priv->center_ratio) * priv->screen_width_pixels / 10); \
+ priv->focus_unitheight = pixel2unit((10 - priv->center_ratio) * priv->screen_height_pixels / 10); \
+}
+
+#define GTK_MAP_MACRO_RECALC_CENTER_BOUNDS() { \
+ priv->min_center.unitx = pixel2unit(grid2pixel(priv->screen_grids_halfwidth)); \
+ priv->min_center.unity = pixel2unit(grid2pixel(priv->screen_grids_halfheight)); \
+ priv->max_center.unitx = GTK_MAP_WORLD_SIZE_UNITS-grid2unit(priv->screen_grids_halfwidth) - 1; \
+ priv->max_center.unity = GTK_MAP_WORLD_SIZE_UNITS-grid2unit(priv->screen_grids_halfheight) - 1; \
}
#define BOUND(x, a, b) { \
static gboolean gtk_map_configure(GtkWidget *widget, GdkEventConfigure *event);
static void gtk_map_scale_draw(GtkWidget *widget, GdkEventExpose *event);
+static void gtk_map_draw_mark(GtkWidget *widget, GdkEventExpose *event);
static gboolean gtk_map_update_buffer_size(GtkMap *map, gint new_width, gint new_height);
GtkMapPriv *priv;
GdkColor color;
-g_debug("MAP: Init");
+g_debug("GTKMAP: Init");
priv=GTK_MAP_GET_PRIVATE(map);
+#ifdef WITH_CAIRO
+priv->ct=gdk_cairo_create(GTK_WIDGET(map)->window);
+#endif
+
priv->zoom=3;
priv->center_mode=CENTER_LATLON;
priv->base_tilex=-5;
priv->scale_rect.x = (priv->screen_width_pixels - SCALE_WIDTH) / 2;
priv->scale_rect.width = SCALE_WIDTH;
-GTK_MAP_MACRO_RECALC_FOCUS_BASE(priv->center_ratio);
-GTK_MAP_MACRO_RECALC_FOCUS_SIZE(priv->center_ratio);
+GTK_MAP_MACRO_RECALC_FOCUS_BASE;
+GTK_MAP_MACRO_RECALC_FOCUS_SIZE;
priv->min_center.unitx = pixel2unit(grid2pixel(priv->screen_grids_halfwidth));
priv->min_center.unity = pixel2unit(grid2pixel(priv->screen_grids_halfheight));
gtk_map_markers_draw(widget, event);
-gtk_map_mark_draw(widget, event);
-
gtk_map_speed_draw(widget, event);
#endif
+gtk_map_mark_draw(widget, event);
gtk_map_scale_draw(widget, event);
return TRUE;
}
+static void
+gtk_map_draw_mark(GtkWidget *widget, GdkEventExpose *event)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+#if 0
+if (!priv->draw_mark)
+ return;
+#endif
+
+if (!gdk_rectangle_intersect(&event->area, &priv->mark_rect, &event->area))
+ return;
+
+#ifdef WITH_CAIRO
+cairo_arc(priv->ct, priv->mark_x1, priv->marky1, priv->draw_width*2, 0, 2 * M_PI);
+cairo_set_source_rgb(priv->ct, 1, 1, 1);
+cairo_fill_preserve(priv->ct);
+cairo_set_source_rgb(priv->ct, 0, 0, 0);
+if (priv->show_velvec) {
+ cairo_save(priv->ct);
+ cairo_set_line_width(priv->ct, priv->draw_width);
+ cairo_move_to(priv->ct, priv->mark_x1, priv->marky1);
+ cairo_line_to(priv->ct, priv->mark_x2, priv->marky2);
+ cairo_restore(priv->ct);
+}
+cairo_stroke(priv->ct);
+#else
+gdk_draw_arc(widget->window,
+ priv->gc_mark,
+ FALSE,
+ priv->mark_x1 - priv->draw_width,
+ priv->mark_y1 - priv->draw_width,
+ 2 * priv->draw_width,
+ 2 * priv->draw_width,
+ 0, 360 * 64);
+
+if (priv->show_velvec)
+ gdk_draw_line(widget->window,
+ priv->gc_velvec,
+ priv->mark_x1, priv->mark_y1,
+ priv->mark_x2, priv->mark_y2);
+#endif
+}
+
+static void
+gtk_map_calculate_mark(GtkWidget *widget)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+priv->mark_x1 = unit2x(priv->location.unitx);
+priv->mark_y1 = unit2y(priv->location.unity);
+priv->mark_x2 = priv->mark_x1 + (priv->show_velvec ? priv->vel_offsetx : 0);
+priv->mark_y2 = priv->mark_y1 + (priv->show_velvec ? priv->vel_offsety : 0);
+
+priv->mark_rect.x= = MIN(priv->mark_x1, priv->mark_x2) - (2 * priv->draw_width);
+priv->mark_rect.y = MIN(priv->mark_y1, priv->mark_y2) - (2 * priv->draw_width);
+priv->mark_rect.width = abs(priv->mark_x1 - priv->mark_x2) + (4 * priv->draw_width);
+priv->mark_rect.height = abs(priv->mark_y1 - priv->mark_y2) + (4 * priv->draw_width);
+}
+
static void
gtk_map_scale_draw(GtkWidget *widget, GdkEventExpose *event)
{
if (priv->speed<0)
return;
-buffer=g_snprintf(buffer, sizeof(buffer), "%0.0f %s", priv->speed * priv->units_conv, priv->units_str);
+g_snprintf(buffer, sizeof(buffer), "%0.0f %s", priv->speed * priv->units_conv, priv->units_str);
map_information_text(10, 10, priv->speed_gc, buffer);
}
}
/**
- * Do an in-place scaling of a pixbuf's pixels at the given ratio from the
- * given source location. It would have been nice if gdk_pixbuf provided
- * this method, but I guess it's not general-purpose enough.
+ * Do an in-place scaling of a pixbuf's pixels at the given ratio from the given source location.
*/
static void
gtk_map_pixbuf_scale_inplace(GdkPixbuf *pixbuf, guint ratio_p2, guint src_x, guint src_y)
/* g_debug("MAP RT: %u %u (%u) %u %u (%u, %u)", tilex, tiley, priv->world_size_tiles, destx, desty, buf_width_tiles, buf_height_tiles); */
-/* The tile is possible. */
for (zoff = (priv->curr_repo->double_size ? 1 : 0); !pixbuf && (priv->zoom + zoff) <= priv->max_zoom && zoff <= GTK_MAP_TILE_SIZE_P2; zoff += 1) {
pixbuf=gtk_map_tile_load(map, tilex, tiley, zoff, !fast_fail);
if (!pixbuf) {
/* Check if we need to blit. */
if (zoff) {
gtk_map_pixbuf_scale_inplace(pixbuf, zoff,
- (tilex - ((tilex >> zoff) << zoff)) << (GTK_MAP_TILE_SIZE_P2 - zoff),
- (tiley - ((tiley >> zoff) << zoff)) << (GTK_MAP_TILE_SIZE_P2 - zoff));
+ (tilex - ((tilex >> zoff) << zoff)) << (GTK_MAP_TILE_SIZE_P2 - zoff),
+ (tiley - ((tiley >> zoff) << zoff)) << (GTK_MAP_TILE_SIZE_P2 - zoff));
image_cache_invalidate_by_image(priv->icache, pixbuf);
}
}
new_base_tilex = grid2tile((gint) pixel2grid((gint)unit2pixel((gint) priv->center.unitx)) - (gint)priv->screen_grids_halfwidth);
new_base_tiley = grid2tile(pixel2grid(unit2pixel(priv->center.unity)) - priv->screen_grids_halfheight);
-/* Same zoom level, so it's likely that we can reuse some of the old
- * buffer's pixels. */
+/* Same zoom level, so it's likely that we can reuse some of the old buffer's pixels. */
if (new_base_tilex != priv->base_tilex || new_base_tiley != priv->base_tiley) {
/* If copying from old parts to new parts, we need to make sure we
return TRUE;
}
-
gint
gtk_map_zoom(GtkWidget *widget, gint zdir)
{