Diff of /trunk/src/osm-gps-map-osd-classic.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 89 by harbaum, Tue Sep 1 11:16:30 2009 UTC revision 108 by harbaum, Fri Sep 11 19:20:55 2009 UTC
# Line 37  Line 37 
37  //the osd controls  //the osd controls
38  typedef struct {  typedef struct {
39      /* the offscreen representation of the OSD */      /* the offscreen representation of the OSD */
40      cairo_surface_t *overlay;      struct {
41            cairo_surface_t *surface;
42            gboolean rendered;
43    #ifdef OSD_GPS_BUTTON
44            gboolean gps_enabled;
45    #endif
46        } controls;
47    
48    #ifdef OSD_SCALE
49        cairo_surface_t *scale;
50        int scale_zoom;
51    #endif
52    
53    #ifdef OSD_CROSSHAIR
54        cairo_surface_t *crosshair;
55    #endif
56    
57    #ifdef OSD_COORDINATES
58        cairo_surface_t *coordinates;
59        float coo_lat, coo_lon;
60    #endif
61    
62  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
63      /* values to handle the "source" menu */      /* values to handle the "source" menu */
# Line 442  osd_source_reallocate(osm_gps_map_osd_t Line 462  osd_source_reallocate(osm_gps_map_osd_t
462    
463      int w = OSD_S_W, h = OSD_S_H;      int w = OSD_S_W, h = OSD_S_H;
464      if(priv->expanded) {      if(priv->expanded) {
         /* ... and right of it the waypoint id */  
465          cairo_text_extents_t extents;          cairo_text_extents_t extents;
466    
467          /* determine content size */          /* determine content size */
# Line 476  osd_source_reallocate(osm_gps_map_osd_t Line 495  osd_source_reallocate(osm_gps_map_osd_t
495          cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w+2, h+2);          cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w+2, h+2);
496    
497      osd_render_source_sel(osd);      osd_render_source_sel(osd);
   
498  }  }
499    
500  #define OSD_HZ      15  #define OSD_HZ      15
# Line 578  osd_source_check(osm_gps_map_osd_t *osd, Line 596  osd_source_check(osm_gps_map_osd_t *osd,
596    
597      /* check for clicks into data area */      /* check for clicks into data area */
598      if(priv->expanded && !priv->handler_id) {      if(priv->expanded && !priv->handler_id) {
599            /* re-adjust from puller top to content top */
600            if(OSD_S_Y < 0)
601                y += OSD_S_EXP_H - OSD_S_PH;
602    
603          if(x > OSD_S_PW &&          if(x > OSD_S_PW &&
604             x < OSD_S_PW + OSD_S_EXP_W &&             x < OSD_S_PW + OSD_S_EXP_W &&
605             y > 0 &&             y > 0 &&
606             y < OSD_S_EXP_H) {             y < OSD_S_EXP_H) {
607    
608              int step = (priv->height - 2*OSD_TEXT_BORDER)              int step = (priv->height - 2*OSD_TEXT_BORDER)
609                  / OSM_GPS_MAP_SOURCE_LAST;                  / OSM_GPS_MAP_SOURCE_LAST;
610    
# Line 716  osd_zoom_labels(cairo_t *cr, gint x, gin Line 738  osd_zoom_labels(cairo_t *cr, gint x, gin
738      cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID);      cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID);
739  }  }
740    
741    #ifdef OSD_COORDINATES
742    
743    #ifndef OSD_COORDINATES_FONT_SIZE
744    #define OSD_COORDINATES_FONT_SIZE 12
745    #endif
746    
747    #define OSD_COORDINATES_OFFSET (OSD_COORDINATES_FONT_SIZE/6)
748    
749    #define OSD_COORDINATES_W  (8*OSD_COORDINATES_FONT_SIZE+2*OSD_COORDINATES_OFFSET)
750    #define OSD_COORDINATES_H  (2*OSD_COORDINATES_FONT_SIZE+OSD_COORDINATES_OFFSET)
751    
752    /* these can be overwritten with versions that support */
753    /* localization */
754    #ifndef OSD_COORDINATES_CHR_N
755    #define OSD_COORDINATES_CHR_N  "N"
756    #endif
757    #ifndef OSD_COORDINATES_CHR_S
758    #define OSD_COORDINATES_CHR_S  "S"
759    #endif
760    #ifndef OSD_COORDINATES_CHR_E
761    #define OSD_COORDINATES_CHR_E  "E"
762    #endif
763    #ifndef OSD_COORDINATES_CHR_W
764    #define OSD_COORDINATES_CHR_W  "W"
765    #endif
766    
767    
768    
769    /* this is the classic geocaching notation */
770    static char
771    *osd_latitude_str(float latitude) {
772        char *c = OSD_COORDINATES_CHR_N;
773        float integral, fractional;
774    
775        if(isnan(latitude))
776            return NULL;
777    
778        if(latitude < 0) {
779            latitude = fabs(latitude);
780            c = OSD_COORDINATES_CHR_S;
781        }
782    
783        fractional = modff(latitude, &integral);
784    
785        return g_strdup_printf("%s %02d° %06.3f'",
786                               c, (int)integral, fractional*60.0);
787    }
788    
789    static char
790    *osd_longitude_str(float longitude) {
791        char *c = OSD_COORDINATES_CHR_E;
792        float integral, fractional;
793    
794        if(isnan(longitude))
795            return NULL;
796    
797        if(longitude < 0) {
798            longitude = fabs(longitude);
799            c = OSD_COORDINATES_CHR_W;
800        }
801    
802        fractional = modff(longitude, &integral);
803    
804        return g_strdup_printf("%s %03d° %06.3f'",
805                               c, (int)integral, fractional*60.0);
806    }
807    
808    static void
809    osd_render_coordinates(osm_gps_map_osd_t *osd)
810    {
811        osd_priv_t *priv = (osd_priv_t*)osd->priv;
812    
813        /* get current map position */
814        gfloat lat, lon;
815        g_object_get(osd->widget, "latitude", &lat, "longitude", &lon, NULL);
816    
817        /* check if position has changed enough to require redraw */
818        if(!isnan(priv->coo_lat) && !isnan(priv->coo_lon))
819            if((fabsf(lat - priv->coo_lat) < 1/60000) &&     /* 1/60000 == 1/1000 minute */
820               (fabsf(lon - priv->coo_lon) < 1/60000))
821                return;
822    
823        priv->coo_lat = lat;
824        priv->coo_lon = lon;
825    
826        /* first fill with light transparency */
827        cairo_t *cr = cairo_create(priv->coordinates);
828        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
829        cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5);
830        cairo_paint(cr);
831        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
832    
833        cairo_select_font_face (cr, "Sans",
834                                CAIRO_FONT_SLANT_NORMAL,
835                                CAIRO_FONT_WEIGHT_BOLD);
836        cairo_set_font_size (cr, OSD_COORDINATES_FONT_SIZE);
837    
838        char *latitude = osd_latitude_str(lat);
839        char *longitude = osd_longitude_str(lon);
840    
841        cairo_text_extents_t lat_extents, lon_extents;
842        cairo_text_extents (cr, latitude, &lat_extents);
843        cairo_text_extents (cr, longitude, &lon_extents);
844    
845        cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
846        cairo_set_line_width (cr, OSD_COORDINATES_FONT_SIZE/6);
847        cairo_move_to (cr,
848                       (OSD_COORDINATES_W - lat_extents.width)/2,
849                       OSD_COORDINATES_OFFSET - lat_extents.y_bearing);
850        cairo_text_path (cr, latitude);
851        cairo_move_to (cr,
852                       (OSD_COORDINATES_W - lon_extents.width)/2,
853                       OSD_COORDINATES_OFFSET - lon_extents.y_bearing +
854                       OSD_COORDINATES_FONT_SIZE);
855        cairo_text_path (cr, longitude);
856        cairo_stroke (cr);
857    
858        cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
859        cairo_move_to (cr,
860                       (OSD_COORDINATES_W - lat_extents.width)/2,
861                       OSD_COORDINATES_OFFSET - lat_extents.y_bearing);
862        cairo_show_text (cr, latitude);
863        cairo_move_to (cr,
864                       (OSD_COORDINATES_W - lon_extents.width)/2,
865                       OSD_COORDINATES_OFFSET - lon_extents.y_bearing +
866                       OSD_COORDINATES_FONT_SIZE);
867        cairo_show_text (cr, longitude);
868    
869        g_free(latitude);
870        g_free(longitude);
871    
872        cairo_destroy(cr);
873    }
874    #endif  // OSD_COORDINATES
875    
876    #ifdef OSD_CROSSHAIR
877    
878    #ifndef OSD_CROSSHAIR_RADIUS
879    #define OSD_CROSSHAIR_RADIUS 10
880    #endif
881    
882    #define OSD_CROSSHAIR_TICK  (OSD_CROSSHAIR_RADIUS/2)
883    #define OSD_CROSSHAIR_BORDER (OSD_CROSSHAIR_TICK + OSD_CROSSHAIR_RADIUS/4)
884    #define OSD_CROSSHAIR_W  ((OSD_CROSSHAIR_RADIUS+OSD_CROSSHAIR_BORDER)*2)
885    #define OSD_CROSSHAIR_H  ((OSD_CROSSHAIR_RADIUS+OSD_CROSSHAIR_BORDER)*2)
886    
887    static void
888    osd_render_crosshair_shape(cairo_t *cr) {
889        cairo_arc (cr, OSD_CROSSHAIR_W/2, OSD_CROSSHAIR_H/2,
890                   OSD_CROSSHAIR_RADIUS, 0,  2*M_PI);
891    
892        cairo_move_to (cr, OSD_CROSSHAIR_W/2 - OSD_CROSSHAIR_RADIUS,
893                       OSD_CROSSHAIR_H/2);
894        cairo_rel_line_to (cr, -OSD_CROSSHAIR_TICK, 0);
895        cairo_move_to (cr, OSD_CROSSHAIR_W/2 + OSD_CROSSHAIR_RADIUS,
896                       OSD_CROSSHAIR_H/2);
897        cairo_rel_line_to (cr,  OSD_CROSSHAIR_TICK, 0);
898    
899        cairo_move_to (cr, OSD_CROSSHAIR_W/2,
900                       OSD_CROSSHAIR_H/2 - OSD_CROSSHAIR_RADIUS);
901        cairo_rel_line_to (cr, 0, -OSD_CROSSHAIR_TICK);
902        cairo_move_to (cr, OSD_CROSSHAIR_W/2,
903                       OSD_CROSSHAIR_H/2 + OSD_CROSSHAIR_RADIUS);
904        cairo_rel_line_to (cr, 0, OSD_CROSSHAIR_TICK);
905    
906        cairo_stroke (cr);
907    }
908    
909    static void
910    osd_render_crosshair(osm_gps_map_osd_t *osd)
911    {
912        osd_priv_t *priv = (osd_priv_t*)osd->priv;
913    
914        /* first fill with transparency */
915        cairo_t *cr = cairo_create(priv->crosshair);
916        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
917        cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
918        //    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2);
919        cairo_paint(cr);
920        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
921    
922        cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);
923    
924        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
925        cairo_set_line_width (cr, OSD_CROSSHAIR_RADIUS/2);
926        osd_render_crosshair_shape(cr);
927    
928        cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5);
929        cairo_set_line_width (cr, OSD_CROSSHAIR_RADIUS/4);
930        osd_render_crosshair_shape(cr);
931    
932        cairo_destroy(cr);
933    }
934    #endif
935    
936    #ifdef OSD_SCALE
937    
938    #ifndef OSD_SCALE_FONT_SIZE
939    #define OSD_SCALE_FONT_SIZE 12
940    #endif
941    #define OSD_SCALE_W   (10*OSD_SCALE_FONT_SIZE)
942    #define OSD_SCALE_H   (5*OSD_SCALE_FONT_SIZE/2)
943    
944    /* various parameters used to create the scale */
945    #define OSD_SCALE_H2   (OSD_SCALE_H/2)
946    #define OSD_SCALE_TICK (2*OSD_SCALE_FONT_SIZE/3)
947    #define OSD_SCALE_M    (OSD_SCALE_H2 - OSD_SCALE_TICK)
948    #define OSD_SCALE_I    (OSD_SCALE_H2 + OSD_SCALE_TICK)
949    #define OSD_SCALE_FD   (OSD_SCALE_FONT_SIZE/4)
950    
951    static void
952    osd_render_scale(osm_gps_map_osd_t *osd)
953    {
954        osd_priv_t *priv = (osd_priv_t*)osd->priv;
955    
956        /* this only needs to be rendered if the zoom has changed */
957        gint zoom;
958        g_object_get(OSM_GPS_MAP(osd->widget), "zoom", &zoom, NULL);
959        if(zoom == priv->scale_zoom)
960            return;
961    
962        priv->scale_zoom = zoom;
963    
964        float m_per_pix = osm_gps_map_get_scale(OSM_GPS_MAP(osd->widget));
965    
966        /* first fill with transparency */
967        cairo_t *cr = cairo_create(priv->scale);
968        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
969        cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0);
970        // pink for testing:    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2);
971        cairo_paint(cr);
972        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
973    
974        /* determine the size of the scale width in meters */
975        float width = (OSD_SCALE_W-OSD_SCALE_FONT_SIZE/6) * m_per_pix;
976    
977        /* scale this to useful values */
978        int exp = logf(width)*M_LOG10E;
979        int mant = width/pow(10,exp);
980        int width_metric = mant * pow(10,exp);
981        char *dist_str = NULL;
982        if(width_metric<1000)
983            dist_str = g_strdup_printf("%u m", width_metric);
984        else
985            dist_str = g_strdup_printf("%u km", width_metric/1000);
986        width_metric /= m_per_pix;
987    
988        /* and now the hard part: scale for useful imperial values :-( */
989        /* try to convert to feet, 1ft == 0.3048 m */
990        width /= 0.3048;
991        float imp_scale = 0.3048;
992        char *dist_imp_unit = "ft";
993    
994        if(width >= 100) {
995            /* 1yd == 3 feet */
996            width /= 3.0;
997            imp_scale *= 3.0;
998            dist_imp_unit = "yd";
999    
1000            if(width >= 1760.0) {
1001                /* 1mi == 1760 yd */
1002                width /= 1760.0;
1003                imp_scale *= 1760.0;
1004                dist_imp_unit = "mi";
1005            }
1006        }
1007    
1008        /* also convert this to full tens/hundreds */
1009        exp = logf(width)*M_LOG10E;
1010        mant = width/pow(10,exp);
1011        int width_imp = mant * pow(10,exp);
1012        char *dist_str_imp = g_strdup_printf("%u %s", width_imp, dist_imp_unit);
1013    
1014        /* convert back to pixels */
1015        width_imp *= imp_scale;
1016        width_imp /= m_per_pix;
1017    
1018        cairo_select_font_face (cr, "Sans",
1019                                CAIRO_FONT_SLANT_NORMAL,
1020                                CAIRO_FONT_WEIGHT_BOLD);
1021        cairo_set_font_size (cr, OSD_SCALE_FONT_SIZE);
1022        cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
1023    
1024        cairo_text_extents_t extents;
1025        cairo_text_extents (cr, dist_str, &extents);
1026    
1027        cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
1028        cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/6);
1029        cairo_move_to (cr, 2*OSD_SCALE_FD, OSD_SCALE_H2-OSD_SCALE_FD);
1030        cairo_text_path (cr, dist_str);
1031        cairo_stroke (cr);
1032        cairo_move_to (cr, 2*OSD_SCALE_FD,
1033                       OSD_SCALE_H2+OSD_SCALE_FD + extents.height);
1034        cairo_text_path (cr, dist_str_imp);
1035        cairo_stroke (cr);
1036    
1037        cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
1038        cairo_move_to (cr, 2*OSD_SCALE_FD, OSD_SCALE_H2-OSD_SCALE_FD);
1039        cairo_show_text (cr, dist_str);
1040        cairo_move_to (cr, 2*OSD_SCALE_FD,
1041                       OSD_SCALE_H2+OSD_SCALE_FD + extents.height);
1042        cairo_show_text (cr, dist_str_imp);
1043    
1044        g_free(dist_str);
1045        g_free(dist_str_imp);
1046    
1047        /* draw white line */
1048        cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);
1049        cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
1050        cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/3);
1051        cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_M);
1052        cairo_rel_line_to (cr, 0,  OSD_SCALE_TICK);
1053        cairo_rel_line_to (cr, width_metric, 0);
1054        cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK);
1055        cairo_stroke(cr);
1056        cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_I);
1057        cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK);
1058        cairo_rel_line_to (cr, width_imp, 0);
1059        cairo_rel_line_to (cr, 0, +OSD_SCALE_TICK);
1060        cairo_stroke(cr);
1061    
1062        /* draw black line */
1063        cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
1064        cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/6);
1065        cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_M);
1066        cairo_rel_line_to (cr, 0,  OSD_SCALE_TICK);
1067        cairo_rel_line_to (cr, width_metric, 0);
1068        cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK);
1069        cairo_stroke(cr);
1070        cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_I);
1071        cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK);
1072        cairo_rel_line_to (cr, width_imp, 0);
1073        cairo_rel_line_to (cr, 0, +OSD_SCALE_TICK);
1074        cairo_stroke(cr);
1075    
1076        cairo_destroy(cr);
1077    }
1078    #endif
1079    
1080  static void  static void
1081  osd_render(osm_gps_map_osd_t *osd) {  osd_render_controls(osm_gps_map_osd_t *osd)
1082    {
1083      osd_priv_t *priv = (osd_priv_t*)osd->priv;      osd_priv_t *priv = (osd_priv_t*)osd->priv;
1084    
1085        if(priv->controls.rendered
1086    #ifdef OSD_GPS_BUTTON
1087           && (priv->controls.gps_enabled == (osd->cb != NULL))
1088    #endif
1089           )
1090            return;
1091    
1092    #ifdef OSD_GPS_BUTTON
1093        priv->controls.gps_enabled = (osd->cb != NULL);
1094    #endif
1095    
1096  #ifndef OSD_COLOR  #ifndef OSD_COLOR
1097      GdkColor bg = GTK_WIDGET(osd->widget)->style->bg[GTK_STATE_NORMAL];      GdkColor bg = GTK_WIDGET(osd->widget)->style->bg[GTK_STATE_NORMAL];
1098      GdkColor fg = GTK_WIDGET(osd->widget)->style->fg[GTK_STATE_NORMAL];      GdkColor fg = GTK_WIDGET(osd->widget)->style->fg[GTK_STATE_NORMAL];
# Line 727  osd_render(osm_gps_map_osd_t *osd) { Line 1100  osd_render(osm_gps_map_osd_t *osd) {
1100  #endif  #endif
1101    
1102      /* first fill with transparency */      /* first fill with transparency */
1103      cairo_t *cr = cairo_create(priv->overlay);      cairo_t *cr = cairo_create(priv->controls.surface);
1104      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1105      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.0);
1106      cairo_paint(cr);      cairo_paint(cr);
# Line 798  osd_render(osm_gps_map_osd_t *osd) { Line 1171  osd_render(osm_gps_map_osd_t *osd) {
1171      cairo_stroke(cr);      cairo_stroke(cr);
1172    
1173      cairo_destroy(cr);      cairo_destroy(cr);
1174    }
1175    
1176    static void
1177    osd_render(osm_gps_map_osd_t *osd)
1178    {
1179        osd_render_controls(osd);
1180    
1181  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
1182      osd_render_source_sel(osd);      osd_render_source_sel(osd);
1183  #endif  #endif
1184    
1185    #ifdef OSD_SCALE
1186        osd_render_scale(osd);
1187    #endif
1188    
1189    #ifdef OSD_CROSSHAIR
1190        osd_render_crosshair(osd);
1191    #endif
1192    
1193    #ifdef OSD_COORDINATES
1194        osd_render_coordinates(osd);
1195    #endif
1196  }  }
1197    
1198  static void  static void
# Line 811  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1202  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1202    
1203      /* OSD itself uses some off-screen rendering, so check if the */      /* OSD itself uses some off-screen rendering, so check if the */
1204      /* offscreen buffer is present and create it if not */      /* offscreen buffer is present and create it if not */
1205      if(!priv->overlay) {      if(!priv->controls.surface) {
1206          /* create overlay ... */          /* create overlay ... */
1207          priv->overlay =          priv->controls.surface =
1208              cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W+2, OSD_H+2);              cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W+2, OSD_H+2);
1209    
1210            priv->controls.rendered = FALSE;
1211    #ifdef OSD_GPS_BUTTON
1212            priv->controls.gps_enabled = FALSE;
1213    #endif
1214    
1215  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
1216          /* the initial OSD state is alway not-expanded */          /* the initial OSD state is alway not-expanded */
1217          priv->map_source =          priv->map_source =
# Line 823  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1219  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1219                                             OSD_S_W+2, OSD_S_H+2);                                             OSD_S_W+2, OSD_S_H+2);
1220  #endif  #endif
1221    
1222    #ifdef OSD_SCALE
1223            priv->scale =
1224                cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1225                                           OSD_SCALE_W, OSD_SCALE_H);
1226            priv->scale_zoom = -1;
1227    #endif
1228    
1229    #ifdef OSD_CROSSHAIR
1230            priv->crosshair =
1231                cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1232                                           OSD_CROSSHAIR_W, OSD_CROSSHAIR_H);
1233    #endif
1234    
1235    #ifdef OSD_COORDINATES
1236            priv->coordinates =
1237                cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1238                                           OSD_COORDINATES_W, OSD_COORDINATES_H);
1239    
1240            priv->coo_lat = priv->coo_lon = OSM_GPS_MAP_INVALID;
1241    #endif
1242    
1243          /* ... and render it */          /* ... and render it */
1244          osd_render(osd);          osd_render(osd);
1245      }      }
# Line 830  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1247  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1247      // now draw this onto the original context      // now draw this onto the original context
1248      cairo_t *cr = gdk_cairo_create(drawable);      cairo_t *cr = gdk_cairo_create(drawable);
1249    
1250      int x = OSD_X, y = OSD_Y;      int x, y;
     if(OSD_X < 0)  
         x = osd->widget->allocation.width - OSD_W + OSD_X;  
1251    
1252      if(OSD_Y < 0)  #ifdef OSD_SCALE
1253          y = osd->widget->allocation.height - OSD_H + OSD_Y;      x =  OSD_X;
1254        y = -OSD_Y;
1255        if(x < 0) x += osd->widget->allocation.width - OSD_SCALE_W;
1256        if(y < 0) y += osd->widget->allocation.height - OSD_SCALE_H;
1257    
1258        cairo_set_source_surface(cr, priv->scale, x, y);
1259        cairo_paint(cr);
1260    #endif
1261    
1262    #ifdef OSD_CROSSHAIR
1263        x = (osd->widget->allocation.width - OSD_CROSSHAIR_W)/2;
1264        y = (osd->widget->allocation.height - OSD_CROSSHAIR_H)/2;
1265    
1266        cairo_set_source_surface(cr, priv->crosshair, x, y);
1267        cairo_paint(cr);
1268    #endif
1269    
1270    #ifdef OSD_COORDINATES
1271        x = -OSD_X;
1272        y = -OSD_Y;
1273        if(x < 0) x += osd->widget->allocation.width - OSD_COORDINATES_W;
1274        if(y < 0) y += osd->widget->allocation.height - OSD_COORDINATES_H;
1275    
1276      cairo_set_source_surface(cr, priv->overlay, x, y);      cairo_set_source_surface(cr, priv->coordinates, x, y);
1277        cairo_paint(cr);
1278    #endif
1279    
1280        x = OSD_X;
1281        if(x < 0)
1282            x += osd->widget->allocation.width - OSD_W;
1283    
1284        y = OSD_Y;
1285        if(y < 0)
1286            y += osd->widget->allocation.height - OSD_H;
1287    
1288        cairo_set_source_surface(cr, priv->controls.surface, x, y);
1289      cairo_paint(cr);      cairo_paint(cr);
1290    
1291  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
# Line 870  osd_free(osm_gps_map_osd_t *osd) Line 1318  osd_free(osm_gps_map_osd_t *osd)
1318  {  {
1319      osd_priv_t *priv = (osd_priv_t *)(osd->priv);      osd_priv_t *priv = (osd_priv_t *)(osd->priv);
1320    
1321      if (priv->overlay)      if (priv->controls.surface)
1322           cairo_surface_destroy(priv->overlay);           cairo_surface_destroy(priv->controls.surface);
1323    
1324  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
1325      if(priv->handler_id)      if(priv->handler_id)
# Line 881  osd_free(osm_gps_map_osd_t *osd) Line 1329  osd_free(osm_gps_map_osd_t *osd)
1329           cairo_surface_destroy(priv->map_source);           cairo_surface_destroy(priv->map_source);
1330  #endif  #endif
1331    
1332    #ifdef OSD_SCALE
1333        if (priv->scale)
1334             cairo_surface_destroy(priv->scale);
1335    #endif
1336    
1337    #ifdef OSD_CROSSHAIR
1338        if (priv->crosshair)
1339             cairo_surface_destroy(priv->crosshair);
1340    #endif
1341    
1342    #ifdef OSD_COORDINATES
1343        if (priv->coordinates)
1344             cairo_surface_destroy(priv->coordinates);
1345    #endif
1346    
1347      g_free(priv);      g_free(priv);
1348  }  }
1349    

Legend:
Removed from v.89  
changed lines
  Added in v.108