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

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

revision 105 by harbaum, Wed Sep 9 19:57:45 2009 UTC revision 107 by harbaum, Fri Sep 11 12:16:50 2009 UTC
# Line 25  Line 25 
25  /* OSD_DIAMETER */  /* OSD_DIAMETER */
26  /* OSD_X, OSD_Y */  /* OSD_X, OSD_Y */
27    
 #define OSD_CROSSHAIR  
   
28  #ifndef USE_CAIRO  #ifndef USE_CAIRO
29  #error "OSD control display lacks a non-cairo implementation!"  #error "OSD control display lacks a non-cairo implementation!"
30  #endif  #endif
# Line 50  typedef struct { Line 48  typedef struct {
48      cairo_surface_t *crosshair;      cairo_surface_t *crosshair;
49  #endif  #endif
50    
51    #ifdef OSD_COORDINATES
52        cairo_surface_t *coordinates;
53    #endif
54    
55  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
56      /* values to handle the "source" menu */      /* values to handle the "source" menu */
57      cairo_surface_t *map_source;      cairo_surface_t *map_source;
# Line 729  osd_zoom_labels(cairo_t *cr, gint x, gin Line 731  osd_zoom_labels(cairo_t *cr, gint x, gin
731      cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID);      cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID);
732  }  }
733    
734    #ifdef OSD_COORDINATES
735    
736    #ifndef OSD_COORDINATES_FONT_SIZE
737    #define OSD_COORDINATES_FONT_SIZE 12
738    #endif
739    
740    #define OSD_COORDINATES_W  (9*OSD_COORDINATES_FONT_SIZE)
741    #define OSD_COORDINATES_H  (2*OSD_COORDINATES_FONT_SIZE)
742    
743    /* these can be overwritten with versions that support */
744    /* localization */
745    #ifndef OSD_COORDINATES_CHR_N
746    #define OSD_COORDINATES_CHR_N  "N"
747    #endif
748    #ifndef OSD_COORDINATES_CHR_S
749    #define OSD_COORDINATES_CHR_S  "S"
750    #endif
751    #ifndef OSD_COORDINATES_CHR_E
752    #define OSD_COORDINATES_CHR_E  "E"
753    #endif
754    #ifndef OSD_COORDINATES_CHR_W
755    #define OSD_COORDINATES_CHR_W  "W"
756    #endif
757    
758    
759    
760    /* this is the classic geocaching notation */
761    static char
762    *osd_latitude_str(float latitude) {
763        char *c = OSD_COORDINATES_CHR_N;
764        float integral, fractional;
765    
766        if(isnan(latitude))
767            return NULL;
768    
769        if(latitude < 0) {
770            latitude = fabs(latitude);
771            c = OSD_COORDINATES_CHR_S;
772        }
773    
774        fractional = modff(latitude, &integral);
775    
776        return g_strdup_printf("%s %02d° %06.3f'",
777                               c, (int)integral, fractional*60.0);
778    }
779    
780    static char
781    *osd_longitude_str(float longitude) {
782        char *c = OSD_COORDINATES_CHR_E;
783        float integral, fractional;
784    
785        if(isnan(longitude))
786            return NULL;
787    
788        if(longitude < 0) {
789            longitude = fabs(longitude);
790            c = OSD_COORDINATES_CHR_W;
791        }
792    
793        fractional = modff(longitude, &integral);
794    
795        return g_strdup_printf("%s %03d° %06.3f'",
796                               c, (int)integral, fractional*60.0);
797    }
798    
799    #define OSD_COORDINATES_OFFSET (OSD_COORDINATES_FONT_SIZE/6)
800    
801    static void
802    osd_render_coordinates(osm_gps_map_osd_t *osd)
803    {
804        osd_priv_t *priv = (osd_priv_t*)osd->priv;
805    
806        /* get current map position */
807        gfloat lat, lon;
808        g_object_get(osd->widget, "latitude", &lat, "longitude", &lon, NULL);
809    
810        /* first fill with transparency */
811        cairo_t *cr = cairo_create(priv->coordinates);
812        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
813        //    cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
814        cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2);
815        cairo_paint(cr);
816        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
817    
818        cairo_select_font_face (cr, "Sans",
819                                CAIRO_FONT_SLANT_NORMAL,
820                                CAIRO_FONT_WEIGHT_BOLD);
821        cairo_set_font_size (cr, OSD_COORDINATES_FONT_SIZE);
822    
823        char *latitude = osd_latitude_str(lat);
824        char *longitude = osd_longitude_str(lon);
825    
826        cairo_text_extents_t lat_extents, lon_extents;
827        cairo_text_extents (cr, latitude, &lat_extents);
828        cairo_text_extents (cr, longitude, &lon_extents);
829    
830        cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
831        cairo_set_line_width (cr, OSD_COORDINATES_FONT_SIZE/6);
832        cairo_move_to (cr,
833                       OSD_COORDINATES_OFFSET - lat_extents.x_bearing,
834                       OSD_COORDINATES_OFFSET - lat_extents.y_bearing);
835        cairo_text_path (cr, latitude);
836        cairo_move_to (cr,
837                       OSD_COORDINATES_OFFSET - lon_extents.x_bearing,
838                       OSD_COORDINATES_OFFSET - lon_extents.y_bearing +
839                       OSD_COORDINATES_FONT_SIZE);
840        cairo_text_path (cr, longitude);
841        cairo_stroke (cr);
842    
843        cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
844        cairo_move_to (cr,
845                       OSD_COORDINATES_OFFSET - lat_extents.x_bearing,
846                       OSD_COORDINATES_OFFSET - lat_extents.y_bearing);
847        cairo_show_text (cr, latitude);
848        cairo_move_to (cr,
849                       OSD_COORDINATES_OFFSET - lon_extents.x_bearing,
850                       OSD_COORDINATES_OFFSET - lon_extents.y_bearing +
851                       OSD_COORDINATES_FONT_SIZE);
852        cairo_show_text (cr, longitude);
853    
854        g_free(latitude);
855        g_free(longitude);
856    
857        cairo_destroy(cr);
858    }
859    #endif  // OSD_COORDINATES
860    
861  #ifdef OSD_CROSSHAIR  #ifdef OSD_CROSSHAIR
862    
863  #ifndef OSD_CROSSHAIR_RADIUS  #ifndef OSD_CROSSHAIR_RADIUS
864  #define OSD_CROSSHAIR_RADIUS 20  #define OSD_CROSSHAIR_RADIUS 10
865  #endif  #endif
866    
867  #define OSD_CROSSHAIR_W  (OSD_CROSSHAIR_RADIUS*2)  #define OSD_CROSSHAIR_TICK  (OSD_CROSSHAIR_RADIUS/2)
868  #define OSD_CROSSHAIR_H  (OSD_CROSSHAIR_RADIUS*2)  #define OSD_CROSSHAIR_BORDER (OSD_CROSSHAIR_TICK + OSD_CROSSHAIR_RADIUS/4)
869    #define OSD_CROSSHAIR_W  ((OSD_CROSSHAIR_RADIUS+OSD_CROSSHAIR_BORDER)*2)
870    #define OSD_CROSSHAIR_H  ((OSD_CROSSHAIR_RADIUS+OSD_CROSSHAIR_BORDER)*2)
871    
872    static void
873    osd_render_crosshair_shape(cairo_t *cr) {
874        cairo_arc (cr, OSD_CROSSHAIR_W/2, OSD_CROSSHAIR_H/2,
875                   OSD_CROSSHAIR_RADIUS, 0,  2*M_PI);
876    
877        cairo_move_to (cr, OSD_CROSSHAIR_W/2 - OSD_CROSSHAIR_RADIUS,
878                       OSD_CROSSHAIR_H/2);
879        cairo_rel_line_to (cr, -OSD_CROSSHAIR_TICK, 0);
880        cairo_move_to (cr, OSD_CROSSHAIR_W/2 + OSD_CROSSHAIR_RADIUS,
881                       OSD_CROSSHAIR_H/2);
882        cairo_rel_line_to (cr,  OSD_CROSSHAIR_TICK, 0);
883    
884        cairo_move_to (cr, OSD_CROSSHAIR_W/2,
885                       OSD_CROSSHAIR_H/2 - OSD_CROSSHAIR_RADIUS);
886        cairo_rel_line_to (cr, 0, -OSD_CROSSHAIR_TICK);
887        cairo_move_to (cr, OSD_CROSSHAIR_W/2,
888                       OSD_CROSSHAIR_H/2 + OSD_CROSSHAIR_RADIUS);
889        cairo_rel_line_to (cr, 0, OSD_CROSSHAIR_TICK);
890    
891        cairo_stroke (cr);
892    }
893    
894  static void  static void
895  osd_render_crosshair(osm_gps_map_osd_t *osd)  osd_render_crosshair(osm_gps_map_osd_t *osd)
# Line 746  osd_render_crosshair(osm_gps_map_osd_t * Line 899  osd_render_crosshair(osm_gps_map_osd_t *
899      /* first fill with transparency */      /* first fill with transparency */
900      cairo_t *cr = cairo_create(priv->crosshair);      cairo_t *cr = cairo_create(priv->crosshair);
901      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
902      //    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0);      cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
903      cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2);      //    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2);
904      cairo_paint(cr);      cairo_paint(cr);
905      cairo_set_operator(cr, CAIRO_OPERATOR_OVER);      cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
906    
907        cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);
908    
909        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
910        cairo_set_line_width (cr, OSD_CROSSHAIR_RADIUS/2);
911        osd_render_crosshair_shape(cr);
912    
913        cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5);
914        cairo_set_line_width (cr, OSD_CROSSHAIR_RADIUS/4);
915        osd_render_crosshair_shape(cr);
916    
917      cairo_destroy(cr);      cairo_destroy(cr);
918  }  }
919  #endif  #endif
# Line 994  osd_render(osm_gps_map_osd_t *osd) Line 1157  osd_render(osm_gps_map_osd_t *osd)
1157  #ifdef OSD_CROSSHAIR  #ifdef OSD_CROSSHAIR
1158      osd_render_crosshair(osd);      osd_render_crosshair(osd);
1159  #endif  #endif
1160    
1161    #ifdef OSD_COORDINATES
1162        osd_render_coordinates(osd);
1163    #endif
1164  }  }
1165    
1166  static void  static void
# Line 1028  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1195  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1195                                         OSD_CROSSHAIR_W, OSD_CROSSHAIR_H);                                         OSD_CROSSHAIR_W, OSD_CROSSHAIR_H);
1196  #endif  #endif
1197    
1198    #ifdef OSD_COORDINATES
1199            priv->coordinates =
1200                cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1201                                           OSD_COORDINATES_W, OSD_COORDINATES_H);
1202    #endif
1203    
1204          /* ... and render it */          /* ... and render it */
1205          osd_render(osd);          osd_render(osd);
1206      }      }
# Line 1035  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1208  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1208      // now draw this onto the original context      // now draw this onto the original context
1209      cairo_t *cr = gdk_cairo_create(drawable);      cairo_t *cr = gdk_cairo_create(drawable);
1210    
1211      int x = OSD_X, y = OSD_Y;      int x, y;
     if(OSD_X < 0)  
         x = osd->widget->allocation.width - OSD_W + OSD_X;  
1212    
1213      if(OSD_Y < 0)  #ifdef OSD_SCALE
1214          y = osd->widget->allocation.height - OSD_H + OSD_Y;      x =  OSD_X;
1215        y = -OSD_Y;
1216        if(x < 0) x += osd->widget->allocation.width - OSD_SCALE_W;
1217        if(y < 0) y += osd->widget->allocation.height - OSD_SCALE_H;
1218    
1219        cairo_set_source_surface(cr, priv->scale, x, y);
1220        cairo_paint(cr);
1221    #endif
1222    
1223    #ifdef OSD_CROSSHAIR
1224        x = (osd->widget->allocation.width - OSD_CROSSHAIR_W)/2;
1225        y = (osd->widget->allocation.height - OSD_CROSSHAIR_H)/2;
1226    
1227        cairo_set_source_surface(cr, priv->crosshair, x, y);
1228        cairo_paint(cr);
1229    #endif
1230    
1231    #ifdef OSD_COORDINATES
1232        x = -OSD_X;
1233        y = -OSD_Y;
1234        if(x < 0) x += osd->widget->allocation.width - OSD_COORDINATES_W;
1235        if(y < 0) y += osd->widget->allocation.height - OSD_COORDINATES_H;
1236    
1237        cairo_set_source_surface(cr, priv->coordinates, x, y);
1238        cairo_paint(cr);
1239    #endif
1240    
1241        x = OSD_X;
1242        if(x < 0)
1243            x += osd->widget->allocation.width - OSD_W;
1244    
1245        y = OSD_Y;
1246        if(y < 0)
1247            y += osd->widget->allocation.height - OSD_H;
1248    
1249      cairo_set_source_surface(cr, priv->overlay, x, y);      cairo_set_source_surface(cr, priv->overlay, x, y);
1250      cairo_paint(cr);      cairo_paint(cr);
# Line 1067  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1271  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1271      cairo_paint(cr);      cairo_paint(cr);
1272  #endif  #endif
1273    
 #ifdef OSD_SCALE  
     x =  OSD_X;  
     y = -OSD_Y;  
     if(x < 0) x += osd->widget->allocation.width - OSD_SCALE_W;  
     if(y < 0) y += osd->widget->allocation.height - OSD_SCALE_H;  
   
     cairo_set_source_surface(cr, priv->scale, x, y);  
     cairo_paint(cr);  
 #endif  
   
 #ifdef OSD_CROSSHAIR  
     x = (osd->widget->allocation.width - OSD_CROSSHAIR_W)/2;  
     y = (osd->widget->allocation.height - OSD_CROSSHAIR_H)/2;  
   
     cairo_set_source_surface(cr, priv->crosshair, x, y);  
     cairo_paint(cr);  
 #endif  
   
1274      cairo_destroy(cr);      cairo_destroy(cr);
1275  }  }
1276    
# Line 1114  osd_free(osm_gps_map_osd_t *osd) Line 1300  osd_free(osm_gps_map_osd_t *osd)
1300           cairo_surface_destroy(priv->crosshair);           cairo_surface_destroy(priv->crosshair);
1301  #endif  #endif
1302    
1303    #ifdef OSD_COORDINATES
1304        if (priv->coordinates)
1305             cairo_surface_destroy(priv->coordinates);
1306    #endif
1307    
1308      g_free(priv);      g_free(priv);
1309  }  }
1310    

Legend:
Removed from v.105  
changed lines
  Added in v.107