#define DEBUG_MAP_TIME 1
+/* Initial size */
+#define BUF_WIDTH_TILES (4)
+#define BUF_HEIGHT_TILES (3)
+#define BUF_WIDTH_PIXELS (1024)
+#define BUF_HEIGHT_PIXELS (768)
+
+static guint buf_width_tiles=BUF_WIDTH_TILES;
+static guint buf_height_tiles=BUF_HEIGHT_TILES;
+static guint buf_width_pixels=BUF_WIDTH_PIXELS;
+static guint buf_height_pixels=BUF_HEIGHT_PIXELS;
+
/** The "base tile" is the upper-left tile in the pixmap. */
guint _base_tilex = -5;
guint _base_tiley = -5;
static PangoLayout *speed_layout;
static PangoFontDescription *speed_fontdesc;
+#ifdef WITH_CAIRO
+cairo_t *ct_pixmap;
+#endif
+
static gint zoom_timeout_sid=0;
static gint map_mode=0;
static gboolean map_data_needs_refresh=FALSE;
{
GtkWidget *map_widget;
+g_debug("MAP: new");
map_widget=gtk_drawing_area_new();
g_signal_connect_after(G_OBJECT(map_widget), "realize", G_CALLBACK(map_cb_after_realize), NULL);
g_signal_connect(G_OBJECT(map_widget), "configure_event", G_CALLBACK(map_cb_configure), NULL);
{
GdkColor color;
-_map_pixmap=gdk_pixmap_new(map_widget->window, BUF_WIDTH_PIXELS, BUF_HEIGHT_PIXELS, -1);
+g_debug("MAP: after_realize");
scale_context=gtk_widget_get_pango_context(map_widget);
scale_layout=pango_layout_new(scale_context);
static gboolean
map_cb_configure(GtkWidget *widget, GdkEventConfigure *event)
{
+guint tw, th;
+
+tw=TILE_SIZE_PIXELS*((widget->allocation.width/TILE_SIZE_PIXELS)+2);
+th=TILE_SIZE_PIXELS*((widget->allocation.height/TILE_SIZE_PIXELS)+2);
+
+g_debug("MAP: configure %d %d -> (%d,%d)", widget->allocation.width, widget->allocation.height, tw, th);
+
+if (_map_pixmap==NULL) {
+ g_debug("Initial buffer pixmap");
+ _map_pixmap=gdk_pixmap_new(widget->window, tw, th, -1);
+} else {
+ if (tw>buf_width_pixels || th>buf_height_pixels) {
+ g_debug("Resize buffer pixmap");
+ g_object_unref(_map_pixmap);
+ _map_pixmap=gdk_pixmap_new(widget->window, tw, th, -1);
+ map_force_redraw();
+ }
+}
-_screen_width_pixels = _map_widget->allocation.width;
-_screen_height_pixels = _map_widget->allocation.height;
+buf_width_pixels=tw;
+buf_height_pixels=th;
+buf_width_tiles=buf_width_pixels/TILE_SIZE_PIXELS;
+buf_height_tiles=buf_height_pixels/TILE_SIZE_PIXELS;
+
+_screen_width_pixels = widget->allocation.width;
+_screen_height_pixels = widget->allocation.height;
_screen_grids_halfwidth = pixel2grid(_screen_width_pixels) / 2;
_screen_grids_halfheight = pixel2grid(_screen_height_pixels) / 2;
return pixbuf;
}
-void
+gboolean
map_render_tile(guint tilex, guint tiley, guint destx, guint desty, gboolean fast_fail)
{
GdkPixbuf *pixbuf=NULL;
gint zoff;
+g_debug("MAP RT: %d %d %d %d (%d, %d)", tilex, tiley, destx, desty, buf_width_tiles, buf_height_tiles);
+
+if (destx > buf_width_pixels || desty > buf_height_pixels)
+ return FALSE;
+
if (tilex<_world_size_tiles && tiley<_world_size_tiles) {
/* The tile is possible. */
for (zoff = (_curr_repo->double_size ? 1 : 0); !pixbuf && (_zoom + zoff) <= MAX_ZOOM && zoff <= TILE_SIZE_P2; zoff += 1) {
if (pixbuf) {
gdk_draw_pixbuf(_map_pixmap, _gc[COLORABLE_MARK], pixbuf, 0, 0, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS, GDK_RGB_DITHER_NONE, 0, 0);
g_object_unref(pixbuf);
- return;
+ return TRUE;
}
gdk_draw_rectangle(_map_pixmap, _map_widget->style->black_gc, TRUE, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
+return TRUE;
}
void
if (_home.valid)
map_draw_position_icon(&_home);
if(_show_poi)
- map_render_all_pois();
+ map_render_all_pois(buf_width_pixels, buf_height_pixels);
if(_show_tracks>0)
map_render_paths();
}
g_timer_start(map_timer);
#endif
-for (new_y = 0; new_y < BUF_HEIGHT_TILES; ++new_y)
- for (new_x = 0; new_x < BUF_WIDTH_TILES; ++new_x) {
+for (new_y = 0; new_y < buf_height_tiles; ++new_y)
+ for (new_x = 0; new_x < buf_width_tiles; ++new_x) {
map_render_tile(_base_tilex + new_x,
_base_tiley + new_y,
new_x * TILE_SIZE_PIXELS,
* new_y, old_x, old_y, iox, and ioy with that in mind. */
if (new_base_tiley < _base_tiley) {
/* New is lower than old - start at bottom and go up. */
- new_y = BUF_HEIGHT_TILES - 1;
+ new_y = buf_height_tiles - 1;
ioy = -1;
} else {
/* New is higher than old - start at top and go down. */
}
if (new_base_tilex < _base_tilex) {
/* New is righter than old - start at right and go left. */
- base_new_x = BUF_WIDTH_TILES - 1;
+ base_new_x = buf_width_tiles - 1;
iox = -1;
} else {
/* New is lefter than old - start at left and go right. */
base_old_x = base_new_x + new_base_tilex - _base_tilex;
_base_tilex = new_base_tilex;
_base_tiley = new_base_tiley;
- for (j = 0; j < BUF_HEIGHT_TILES; ++j, new_y += ioy, old_y += ioy) {
+ for (j = 0; j < buf_height_tiles; ++j, new_y += ioy, old_y += ioy) {
new_x = base_new_x;
old_x = base_old_x;
/* Iterate over the x tile values. */
- for (k = 0; k < BUF_WIDTH_TILES; ++k, new_x += iox, old_x += iox) {
+ for (k = 0; k < buf_width_tiles; ++k, new_x += iox, old_x += iox) {
/* Can we get this grid block from the old buffer?. */
- if (old_x >= 0 && old_x < BUF_WIDTH_TILES && old_y >= 0 && old_y < BUF_HEIGHT_TILES) {
+ if (old_x >= 0 && old_x < buf_width_tiles && old_y >= 0 && old_y < buf_height_tiles) {
/* Copy from old buffer to new buffer. */
gdk_draw_drawable(_map_pixmap,
_gc[COLORABLE_MARK],
x1=unit2bufx(x);
y1=unit2bufy(y);
-if ((x1 > BUF_WIDTH_PIXELS) || (y1 > BUF_HEIGHT_PIXELS))
+if ((x1 > buf_width_pixels) || (y1 > buf_height_pixels))
return;
p=gdk_pixbuf_new_from_file(DATADIR "/pixmaps/mapper/home.png", NULL);
* IT IS AN ERROR FOR BOTH POINTS TO INDICATE A BREAK.
*/
void
-map_render_segment(GdkGC * gc_norm, GdkGC * gc_alt, guint unitx1, guint unity1, guint unitx2, guint unity2)
+map_render_segment(GdkGC *gc_norm, GdkGC *gc_alt, guint unitx1, guint unity1, guint unitx2, guint unity2)
{
- if (!unity1) {
- guint x2, y2;
- x2 = unit2bufx(unitx2);
- y2 = unit2bufy(unity2);
- /* Make sure this circle will be visible. */
- if ((x2 < BUF_WIDTH_PIXELS) && (y2 < BUF_HEIGHT_PIXELS))
- gdk_draw_arc(_map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */
- x2 - _draw_width, y2 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */
- 360 * 64);
- } else if (!unity2) {
- guint x1, y1;
- x1 = unit2bufx(unitx1);
- y1 = unit2bufy(unity1);
- /* Make sure this circle will be visible. */
- if ((x1 < BUF_WIDTH_PIXELS) && ((unsigned)y1 < BUF_HEIGHT_PIXELS))
- gdk_draw_arc(_map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */
- x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */
- 360 * 64);
- } else {
- gint x1, y1, x2, y2;
- x1 = unit2bufx(unitx1);
- y1 = unit2bufy(unity1);
- x2 = unit2bufx(unitx2);
- y2 = unit2bufy(unity2);
- /* Make sure this line could possibly be visible. */
- if (!((x1 > BUF_WIDTH_PIXELS && x2 > BUF_WIDTH_PIXELS)
- || (x1 < 0 && x2 < 0)
- || (y1 > BUF_HEIGHT_PIXELS && y2 > BUF_HEIGHT_PIXELS)
- || (y1 < 0 && y2 < 0)))
- gdk_draw_line(_map_pixmap, gc_norm, x1, y1, x2, y2);
+if (!unity1) {
+ guint x2, y2;
+
+ x2 = unit2bufx(unitx2);
+ y2 = unit2bufy(unity2);
+ /* Make sure this circle will be visible. */
+ if ((x2 < buf_width_pixels) && (y2 < buf_height_pixels))
+ gdk_draw_arc(_map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */
+ x2 - _draw_width, y2 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */
+ 360 * 64);
+} else if (!unity2) {
+ guint x1, y1;
+
+ x1 = unit2bufx(unitx1);
+ y1 = unit2bufy(unity1);
+ /* Make sure this circle will be visible. */
+ if ((x1 < buf_width_pixels) && ((unsigned)y1 < buf_height_pixels))
+ gdk_draw_arc(_map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */
+ x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */
+ 360 * 64);
+} else {
+ gint x1, y1, x2, y2;
+
+ x1 = unit2bufx(unitx1);
+ y1 = unit2bufy(unity1);
+ x2 = unit2bufx(unitx2);
+ y2 = unit2bufy(unity2);
+ /* Make sure this line could possibly be visible. */
+ if (!((x1 > buf_width_pixels && x2 > buf_width_pixels)
+ || (x1 < 0 && x2 < 0)
+ || (y1 > buf_height_pixels && y2 > buf_height_pixels)
+ || (y1 < 0 && y2 < 0)))
+ gdk_draw_line(_map_pixmap, gc_norm, x1, y1, x2, y2);
}
}
+void
+map_render_waypoint(guint x1, guint y1, GdkGC ** gc)
+{
+if ((x1 > buf_width_pixels) || (y1 > buf_height_pixels))
+ return;
+gdk_draw_arc(_map_pixmap, gc[1], FALSE, x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, 360 * 64);
+}
+
/**
* Render all track data onto the _map_pixmap. Note that this does not
* clear the pixmap of previous track data (use map_force_redraw() for
void
map_render_path(Path * path, GdkGC ** gc)
{
- Point *curr;
- WayPoint *wcurr;
-
- /* gc is a pointer to the first GC to use (for plain points). (gc + 1)
- * is a pointer to the GC to use for waypoints, and (gc + 2) is a pointer
- * to the GC to use for breaks. */
-
- /* else there is a route to draw. */
- for (curr = path->head, wcurr = path->whead; curr++ != path->tail;) {
- /* Draw the line from (curr - 1) to (curr). */
- map_render_segment(gc[0], gc[2],
- curr[-1].unitx, curr[-1].unity, curr->unitx,
- curr->unity);
-
- /* Now, check if curr is a waypoint. */
- if (wcurr && wcurr <= path->wtail && wcurr->point == curr) {
- guint x1 = unit2bufx(wcurr->point->unitx);
- guint y1 = unit2bufy(wcurr->point->unity);
- if ((x1 < BUF_WIDTH_PIXELS)
- && (y1 < BUF_HEIGHT_PIXELS)) {
- gdk_draw_arc(_map_pixmap, gc[1], FALSE, /* FALSE: not filled. */
- x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */
- 360 * 64);
- }
- wcurr++;
- }
+Point *curr;
+WayPoint *wcurr;
+
+/* gc is a pointer to the first GC to use (for plain points). (gc + 1)
+ * is a pointer to the GC to use for waypoints, and (gc + 2) is a pointer
+ * to the GC to use for breaks. */
+
+/* else there is a route to draw. */
+for (curr = path->head, wcurr = path->whead; curr++ != path->tail;) {
+ /* Draw the line from (curr - 1) to (curr). */
+ map_render_segment(gc[0], gc[2], curr[-1].unitx, curr[-1].unity, curr->unitx, curr->unity);
+
+ /* Now, check if curr is a waypoint. */
+ if (wcurr && wcurr <= path->wtail && wcurr->point == curr) {
+ guint x1 = unit2bufx(wcurr->point->unitx);
+ guint y1 = unit2bufy(wcurr->point->unity);
+
+ map_render_waypoint(x1, y1, _gc[COLORABLE_TRACK_BREAK]);
+ wcurr++;
}
}
+}
void
map_render_paths(void)
guint x1 = unit2bufx(_next_way->point->unitx);
guint y1 = unit2bufy(_next_way->point->unity);
- if ((x1 < BUF_WIDTH_PIXELS) && (y1 < BUF_HEIGHT_PIXELS)) {
+ if ((x1 < buf_width_pixels) && (y1 < buf_height_pixels)) {
/* Draw the next waypoint as a break. */
gdk_draw_arc(_map_pixmap, _gc[COLORABLE_ROUTE_BREAK], FALSE, /* FALSE: not filled. */
x1 - _draw_width, y1 - _draw_width, 4 * _draw_width, 4 * _draw_width, 0, /* start at 0 degrees. */