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

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

revision 99 by harbaum, Mon Sep 7 19:22:02 2009 UTC revision 105 by harbaum, Wed Sep 9 19:57:45 2009 UTC
# Line 25  Line 25 
25  /* OSD_DIAMETER */  /* OSD_DIAMETER */
26  /* OSD_X, OSD_Y */  /* OSD_X, OSD_Y */
27    
28  #define OSD_SCALE  #define OSD_CROSSHAIR
   
 #define OSD_SCALE_W  100  
 #define OSD_SCALE_H   20  
29    
30  #ifndef USE_CAIRO  #ifndef USE_CAIRO
31  #error "OSD control display lacks a non-cairo implementation!"  #error "OSD control display lacks a non-cairo implementation!"
# Line 46  typedef struct { Line 43  typedef struct {
43    
44  #ifdef OSD_SCALE  #ifdef OSD_SCALE
45      cairo_surface_t *scale;      cairo_surface_t *scale;
46        int scale_zoom;
47    #endif
48    
49    #ifdef OSD_CROSSHAIR
50        cairo_surface_t *crosshair;
51  #endif  #endif
52    
53  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
# Line 451  osd_source_reallocate(osm_gps_map_osd_t Line 453  osd_source_reallocate(osm_gps_map_osd_t
453    
454      int w = OSD_S_W, h = OSD_S_H;      int w = OSD_S_W, h = OSD_S_H;
455      if(priv->expanded) {      if(priv->expanded) {
         /* ... and right of it the waypoint id */  
456          cairo_text_extents_t extents;          cairo_text_extents_t extents;
457    
458          /* determine content size */          /* determine content size */
# Line 728  osd_zoom_labels(cairo_t *cr, gint x, gin Line 729  osd_zoom_labels(cairo_t *cr, gint x, gin
729      cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID);      cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID);
730  }  }
731    
732  static char *  #ifdef OSD_CROSSHAIR
733  dist_str_metric(int dist)  
734    #ifndef OSD_CROSSHAIR_RADIUS
735    #define OSD_CROSSHAIR_RADIUS 20
736    #endif
737    
738    #define OSD_CROSSHAIR_W  (OSD_CROSSHAIR_RADIUS*2)
739    #define OSD_CROSSHAIR_H  (OSD_CROSSHAIR_RADIUS*2)
740    
741    static void
742    osd_render_crosshair(osm_gps_map_osd_t *osd)
743  {  {
744      if(dist<1000)      osd_priv_t *priv = (osd_priv_t*)osd->priv;
         return g_strdup_printf("%u m",  dist);  
745    
746      return g_strdup_printf("%u km", dist/1000);      /* first fill with transparency */
747        cairo_t *cr = cairo_create(priv->crosshair);
748        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
749        //    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0);
750        cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2);
751        cairo_paint(cr);
752        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
753    
754        cairo_destroy(cr);
755  }  }
756    #endif
757    
758    #ifdef OSD_SCALE
759    
760    #ifndef OSD_SCALE_FONT_SIZE
761    #define OSD_SCALE_FONT_SIZE 12
762    #endif
763    #define OSD_SCALE_W   (10*OSD_SCALE_FONT_SIZE)
764    #define OSD_SCALE_H   (5*OSD_SCALE_FONT_SIZE/2)
765    
766    /* various parameters used to create the scale */
767    #define OSD_SCALE_H2   (OSD_SCALE_H/2)
768    #define OSD_SCALE_TICK (2*OSD_SCALE_FONT_SIZE/3)
769    #define OSD_SCALE_M    (OSD_SCALE_H2 - OSD_SCALE_TICK)
770    #define OSD_SCALE_I    (OSD_SCALE_H2 + OSD_SCALE_TICK)
771    #define OSD_SCALE_FD   (OSD_SCALE_FONT_SIZE/4)
772    
773  static void  static void
774  osd_render_scale(osm_gps_map_osd_t *osd)  osd_render_scale(osm_gps_map_osd_t *osd)
775  {  {
776      osd_priv_t *priv = (osd_priv_t*)osd->priv;      osd_priv_t *priv = (osd_priv_t*)osd->priv;
777    
778        /* this only needs to be rendered if the zoom has changed */
779        gint zoom;
780        g_object_get(OSM_GPS_MAP(osd->widget), "zoom", &zoom, NULL);
781        if(zoom == priv->scale_zoom)
782            return;
783    
784        priv->scale_zoom = zoom;
785    
786      float m_per_pix = osm_gps_map_get_scale(OSM_GPS_MAP(osd->widget));      float m_per_pix = osm_gps_map_get_scale(OSM_GPS_MAP(osd->widget));
787    
788      /* first fill with transparency */      /* first fill with transparency */
789      cairo_t *cr = cairo_create(priv->scale);      cairo_t *cr = cairo_create(priv->scale);
790      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
791      //    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);
792      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);
793      cairo_paint(cr);      cairo_paint(cr);
794      cairo_set_operator(cr, CAIRO_OPERATOR_OVER);      cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
795    
796      /* determine the size of the scale width in meters */      /* determine the size of the scale width in meters */
797      float width = (OSD_SCALE_W-2) * m_per_pix;      float width = (OSD_SCALE_W-OSD_SCALE_FONT_SIZE/6) * m_per_pix;
798      printf("width = %f meters\n", width);  
   
799      /* scale this to useful values */      /* scale this to useful values */
800      int exp = logf(width)*M_LOG10E;      int exp = logf(width)*M_LOG10E;
801      int mant = width/pow(10,exp);      int mant = width/pow(10,exp);
     printf("mant = %d, exp = %d \n", mant, exp);  
   
802      int width_metric = mant * pow(10,exp);      int width_metric = mant * pow(10,exp);
803      char *dist_str = dist_str_metric(width_metric);      char *dist_str = NULL;
804        if(width_metric<1000)
805            dist_str = g_strdup_printf("%u m", width_metric);
806        else
807            dist_str = g_strdup_printf("%u km", width_metric/1000);
808      width_metric /= m_per_pix;      width_metric /= m_per_pix;
     printf("metric scale width = %d pixels: %s\n", width_metric, dist_str);  
809    
810      int font_size = 12;      /* and now the hard part: scale for useful imperial values :-( */
811        /* try to convert to feet, 1ft == 0.3048 m */
812        width /= 0.3048;
813        float imp_scale = 0.3048;
814        char *dist_imp_unit = "ft";
815    
816        if(width >= 100) {
817            /* 1yd == 3 feet */
818            width /= 3.0;
819            imp_scale *= 3.0;
820            dist_imp_unit = "yd";
821    
822            if(width >= 1760.0) {
823                /* 1mi == 1760 yd */
824                width /= 1760.0;
825                imp_scale *= 1760.0;
826                dist_imp_unit = "mi";
827            }
828        }
829    
830        /* also convert this to full tens/hundreds */
831        exp = logf(width)*M_LOG10E;
832        mant = width/pow(10,exp);
833        int width_imp = mant * pow(10,exp);
834        char *dist_str_imp = g_strdup_printf("%u %s", width_imp, dist_imp_unit);
835    
836        /* convert back to pixels */
837        width_imp *= imp_scale;
838        width_imp /= m_per_pix;
839    
840      cairo_select_font_face (cr, "Sans",      cairo_select_font_face (cr, "Sans",
841                              CAIRO_FONT_SLANT_NORMAL,                              CAIRO_FONT_SLANT_NORMAL,
842                              CAIRO_FONT_WEIGHT_BOLD);                              CAIRO_FONT_WEIGHT_BOLD);
843      cairo_set_font_size (cr, font_size);      cairo_set_font_size (cr, OSD_SCALE_FONT_SIZE);
844      cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);      cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
845    
846      cairo_text_extents_t extents;      cairo_text_extents_t extents;
847      cairo_text_extents (cr, dist_str, &extents);      cairo_text_extents (cr, dist_str, &extents);
848    
849      cairo_move_to (cr, font_size/3, font_size);      cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
850        cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/6);
851        cairo_move_to (cr, 2*OSD_SCALE_FD, OSD_SCALE_H2-OSD_SCALE_FD);
852        cairo_text_path (cr, dist_str);
853        cairo_stroke (cr);
854        cairo_move_to (cr, 2*OSD_SCALE_FD,
855                       OSD_SCALE_H2+OSD_SCALE_FD + extents.height);
856        cairo_text_path (cr, dist_str_imp);
857        cairo_stroke (cr);
858    
859        cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
860        cairo_move_to (cr, 2*OSD_SCALE_FD, OSD_SCALE_H2-OSD_SCALE_FD);
861      cairo_show_text (cr, dist_str);      cairo_show_text (cr, dist_str);
862        cairo_move_to (cr, 2*OSD_SCALE_FD,
863                       OSD_SCALE_H2+OSD_SCALE_FD + extents.height);
864        cairo_show_text (cr, dist_str_imp);
865    
866      printf("height = %f, bearing = %f\n",  extents.height, extents.y_bearing);      g_free(dist_str);
867        g_free(dist_str_imp);
868    
869      /* draw white line */      /* draw white line */
870      cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);      cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);
871      cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);      cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
872      cairo_set_line_width (cr, 3);      cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/3);
873      cairo_move_to (cr, 2, 2*font_size/3);      cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_M);
874      cairo_rel_line_to (cr, 0,  2*font_size/3);      cairo_rel_line_to (cr, 0,  OSD_SCALE_TICK);
875      cairo_rel_line_to (cr, width_metric, 0);      cairo_rel_line_to (cr, width_metric, 0);
876      cairo_rel_line_to (cr, 0, -2*font_size/3);      cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK);
877        cairo_stroke(cr);
878        cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_I);
879        cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK);
880        cairo_rel_line_to (cr, width_imp, 0);
881        cairo_rel_line_to (cr, 0, +OSD_SCALE_TICK);
882      cairo_stroke(cr);      cairo_stroke(cr);
883    
884      /* draw black line */      /* draw black line */
885      cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);      cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
886      cairo_set_line_width (cr, 2);      cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/6);
887      cairo_move_to (cr, 2, 2*font_size/3);      cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_M);
888      cairo_rel_line_to (cr, 0,  2*font_size/3);      cairo_rel_line_to (cr, 0,  OSD_SCALE_TICK);
889      cairo_rel_line_to (cr, width_metric, 0);      cairo_rel_line_to (cr, width_metric, 0);
890      cairo_rel_line_to (cr, 0, -2*font_size/3);      cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK);
891        cairo_stroke(cr);
892        cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_I);
893        cairo_rel_line_to (cr, 0, -OSD_SCALE_TICK);
894        cairo_rel_line_to (cr, width_imp, 0);
895        cairo_rel_line_to (cr, 0, +OSD_SCALE_TICK);
896      cairo_stroke(cr);      cairo_stroke(cr);
   
     /* xyz */  
897    
898      cairo_destroy(cr);      cairo_destroy(cr);
899  }  }
900    #endif
901    
902  static void  static void
903  osd_render(osm_gps_map_osd_t *osd)  osd_render(osm_gps_map_osd_t *osd)
# Line 896  osd_render(osm_gps_map_osd_t *osd) Line 990  osd_render(osm_gps_map_osd_t *osd)
990  #ifdef OSD_SCALE  #ifdef OSD_SCALE
991      osd_render_scale(osd);      osd_render_scale(osd);
992  #endif  #endif
993    
994    #ifdef OSD_CROSSHAIR
995        osd_render_crosshair(osd);
996    #endif
997  }  }
998    
999  static void  static void
# Line 920  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1018  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1018  #ifdef OSD_SCALE  #ifdef OSD_SCALE
1019          priv->scale =          priv->scale =
1020              cairo_image_surface_create(CAIRO_FORMAT_ARGB32,              cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1021                                         OSD_SCALE_W+2, OSD_SCALE_H+2);                                         OSD_SCALE_W, OSD_SCALE_H);
1022            priv->scale_zoom = -1;
1023    #endif
1024    
1025    #ifdef OSD_CROSSHAIR
1026            priv->crosshair =
1027                cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1028                                           OSD_CROSSHAIR_W, OSD_CROSSHAIR_H);
1029  #endif  #endif
1030    
1031          /* ... and render it */          /* ... and render it */
# Line 972  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1077  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1077      cairo_paint(cr);      cairo_paint(cr);
1078  #endif  #endif
1079    
1080    #ifdef OSD_CROSSHAIR
1081        x = (osd->widget->allocation.width - OSD_CROSSHAIR_W)/2;
1082        y = (osd->widget->allocation.height - OSD_CROSSHAIR_H)/2;
1083    
1084        cairo_set_source_surface(cr, priv->crosshair, x, y);
1085        cairo_paint(cr);
1086    #endif
1087    
1088      cairo_destroy(cr);      cairo_destroy(cr);
1089  }  }
1090    
# Line 996  osd_free(osm_gps_map_osd_t *osd) Line 1109  osd_free(osm_gps_map_osd_t *osd)
1109           cairo_surface_destroy(priv->scale);           cairo_surface_destroy(priv->scale);
1110  #endif  #endif
1111    
1112    #ifdef OSD_CROSSHAIR
1113        if (priv->crosshair)
1114             cairo_surface_destroy(priv->crosshair);
1115    #endif
1116    
1117      g_free(priv);      g_free(priv);
1118  }  }
1119    

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