--- trunk/src/osm-gps-map-osd-classic.c 2009/09/08 19:08:37 102 +++ trunk/src/osm-gps-map-osd-classic.c 2009/09/09 11:50:50 103 @@ -25,10 +25,11 @@ /* OSD_DIAMETER */ /* OSD_X, OSD_Y */ -#define OSD_SCALE - -#define OSD_SCALE_W 120 -#define OSD_SCALE_H 20 +#ifndef OSD_SCALE_FONT_SIZE +#define OSD_SCALE_FONT_SIZE 12 +#endif +#define OSD_SCALE_W (10*OSD_SCALE_FONT_SIZE) +#define OSD_SCALE_H (5*OSD_SCALE_FONT_SIZE/2) #ifndef USE_CAIRO #error "OSD control display lacks a non-cairo implementation!" @@ -46,6 +47,7 @@ #ifdef OSD_SCALE cairo_surface_t *scale; + int scale_zoom; #endif #ifdef OSD_SOURCE_SEL @@ -727,40 +729,48 @@ cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID); } -static char * -dist_str_metric(int dist) -{ - if(dist<1000) - return g_strdup_printf("%u m", dist); - - return g_strdup_printf("%u km", dist/1000); -} - -#define OSD_SCALE_FONT_SIZE 12 +/* various parameters used to create the scale */ +#define OSD_SCALE_H2 (OSD_SCALE_H/2) +#define OSD_SCALE_TICK (2*OSD_SCALE_FONT_SIZE/3) +#define OSD_SCALE_M (OSD_SCALE_H2 - OSD_SCALE_TICK) +#define OSD_SCALE_I (OSD_SCALE_H2 + OSD_SCALE_TICK) +#define OSD_SCALE_FD (OSD_SCALE_FONT_SIZE/4) static void osd_render_scale(osm_gps_map_osd_t *osd) { osd_priv_t *priv = (osd_priv_t*)osd->priv; + + /* this only needs to be rendered if the zoom has changed */ + gint zoom; + g_object_get(OSM_GPS_MAP(osd->widget), "zoom", &zoom, NULL); + if(zoom == priv->scale_zoom) + return; + + priv->scale_zoom = zoom; + float m_per_pix = osm_gps_map_get_scale(OSM_GPS_MAP(osd->widget)); /* first fill with transparency */ cairo_t *cr = cairo_create(priv->scale); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0); - // cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2); + // pink for testing: cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2); cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); /* determine the size of the scale width in meters */ - float width = (OSD_SCALE_W-2) * m_per_pix; - printf("%d pixels is %f m\n", OSD_SCALE_W-2, width); + float width = (OSD_SCALE_W-OSD_SCALE_FONT_SIZE/6) * m_per_pix; /* scale this to useful values */ int exp = logf(width)*M_LOG10E; int mant = width/pow(10,exp); int width_metric = mant * pow(10,exp); - char *dist_str = dist_str_metric(width_metric); + char *dist_str = NULL; + if(width_metric<1000) + dist_str = g_strdup_printf("%u m", width_metric); + else + dist_str = g_strdup_printf("%u km", width_metric/1000); width_metric /= m_per_pix; /* and now the hard part: scale for useful imperial values :-( */ @@ -783,8 +793,15 @@ } } - printf("this is %f %s\n", width, dist_imp_unit); - printf("this is %f pixels\n", width * imp_scale / m_per_pix); + /* also convert this to full tens/hundreds */ + exp = logf(width)*M_LOG10E; + mant = width/pow(10,exp); + int width_imp = mant * pow(10,exp); + char *dist_str_imp = g_strdup_printf("%u %s", width_imp, dist_imp_unit); + + /* convert back to pixels */ + width_imp *= imp_scale; + width_imp /= m_per_pix; cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, @@ -796,35 +813,53 @@ cairo_text_extents (cr, dist_str, &extents); cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); - cairo_move_to (cr, OSD_SCALE_FONT_SIZE/3, OSD_SCALE_FONT_SIZE); + cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/6); + cairo_move_to (cr, 2*OSD_SCALE_FD, OSD_SCALE_H2-OSD_SCALE_FD); cairo_text_path (cr, dist_str); - cairo_set_line_width (cr, 2); + cairo_stroke (cr); + cairo_move_to (cr, 2*OSD_SCALE_FD, + OSD_SCALE_H2+OSD_SCALE_FD + extents.height); + cairo_text_path (cr, dist_str_imp); cairo_stroke (cr); cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); - cairo_move_to (cr, OSD_SCALE_FONT_SIZE/3, OSD_SCALE_FONT_SIZE); + cairo_move_to (cr, 2*OSD_SCALE_FD, OSD_SCALE_H2-OSD_SCALE_FD); cairo_show_text (cr, dist_str); + cairo_move_to (cr, 2*OSD_SCALE_FD, + OSD_SCALE_H2+OSD_SCALE_FD + extents.height); + cairo_show_text (cr, dist_str_imp); + + g_free(dist_str); + g_free(dist_str_imp); /* draw white line */ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); - cairo_set_line_width (cr, 4); - cairo_move_to (cr, 2, 2*OSD_SCALE_FONT_SIZE/3); - cairo_rel_line_to (cr, 0, 2*OSD_SCALE_FONT_SIZE/3); + cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/3); + cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_M); + cairo_rel_line_to (cr, 0, OSD_SCALE_TICK); cairo_rel_line_to (cr, width_metric, 0); - cairo_rel_line_to (cr, 0, -2*OSD_SCALE_FONT_SIZE/3); + cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK); + cairo_stroke(cr); + cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_I); + cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK); + cairo_rel_line_to (cr, width_imp, 0); + cairo_rel_line_to (cr, 0, +OSD_SCALE_TICK); cairo_stroke(cr); /* draw black line */ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); - cairo_set_line_width (cr, 2); - cairo_move_to (cr, 2, 2*OSD_SCALE_FONT_SIZE/3); - cairo_rel_line_to (cr, 0, 2*OSD_SCALE_FONT_SIZE/3); + cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/6); + cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_M); + cairo_rel_line_to (cr, 0, OSD_SCALE_TICK); cairo_rel_line_to (cr, width_metric, 0); - cairo_rel_line_to (cr, 0, -2*OSD_SCALE_FONT_SIZE/3); + cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK); + cairo_stroke(cr); + cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_I); + cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK); + cairo_rel_line_to (cr, width_imp, 0); + cairo_rel_line_to (cr, 0, +OSD_SCALE_TICK); cairo_stroke(cr); - - /* xyz */ cairo_destroy(cr); } @@ -944,7 +979,8 @@ #ifdef OSD_SCALE priv->scale = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - OSD_SCALE_W+2, OSD_SCALE_H+2); + OSD_SCALE_W, OSD_SCALE_H); + priv->scale_zoom = -1; #endif /* ... and render it */