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 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_CROSSHAIR
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!"
32  #endif  #endif
# Line 39  typedef struct { Line 41  typedef struct {
41      /* the offscreen representation of the OSD */      /* the offscreen representation of the OSD */
42      cairo_surface_t *overlay;      cairo_surface_t *overlay;
43    
44    #ifdef OSD_SCALE
45        cairo_surface_t *scale;
46        int scale_zoom;
47    #endif
48    
49    #ifdef OSD_CROSSHAIR
50        cairo_surface_t *crosshair;
51    #endif
52    
53  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
54      /* values to handle the "source" menu */      /* values to handle the "source" menu */
55      cairo_surface_t *map_source;      cairo_surface_t *map_source;
# Line 442  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 476  osd_source_reallocate(osm_gps_map_osd_t Line 486  osd_source_reallocate(osm_gps_map_osd_t
486          cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w+2, h+2);          cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w+2, h+2);
487    
488      osd_render_source_sel(osd);      osd_render_source_sel(osd);
   
489  }  }
490    
491  #define OSD_HZ      15  #define OSD_HZ      15
# Line 578  osd_source_check(osm_gps_map_osd_t *osd, Line 587  osd_source_check(osm_gps_map_osd_t *osd,
587    
588      /* check for clicks into data area */      /* check for clicks into data area */
589      if(priv->expanded && !priv->handler_id) {      if(priv->expanded && !priv->handler_id) {
590            /* re-adjust from puller top to content top */
591            if(OSD_S_Y < 0)
592                y += OSD_S_EXP_H - OSD_S_PH;
593    
594          if(x > OSD_S_PW &&          if(x > OSD_S_PW &&
595             x < OSD_S_PW + OSD_S_EXP_W &&             x < OSD_S_PW + OSD_S_EXP_W &&
596             y > 0 &&             y > 0 &&
597             y < OSD_S_EXP_H) {             y < OSD_S_EXP_H) {
598    
599              int step = (priv->height - 2*OSD_TEXT_BORDER)              int step = (priv->height - 2*OSD_TEXT_BORDER)
600                  / OSM_GPS_MAP_SOURCE_LAST;                  / OSM_GPS_MAP_SOURCE_LAST;
601    
# Line 716  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    #ifdef OSD_CROSSHAIR
733    
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        osd_priv_t *priv = (osd_priv_t*)osd->priv;
745    
746        /* 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
774    osd_render_scale(osm_gps_map_osd_t *osd)
775    {
776        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));
787    
788        /* first fill with transparency */
789        cairo_t *cr = cairo_create(priv->scale);
790        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
791        cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0);
792        // pink for testing:    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2);
793        cairo_paint(cr);
794        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
795    
796        /* determine the size of the scale width in meters */
797        float width = (OSD_SCALE_W-OSD_SCALE_FONT_SIZE/6) * m_per_pix;
798    
799        /* scale this to useful values */
800        int exp = logf(width)*M_LOG10E;
801        int mant = width/pow(10,exp);
802        int width_metric = mant * pow(10,exp);
803        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;
809    
810        /* 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",
841                                CAIRO_FONT_SLANT_NORMAL,
842                                CAIRO_FONT_WEIGHT_BOLD);
843        cairo_set_font_size (cr, OSD_SCALE_FONT_SIZE);
844        cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
845    
846        cairo_text_extents_t extents;
847        cairo_text_extents (cr, dist_str, &extents);
848    
849        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);
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        g_free(dist_str);
867        g_free(dist_str_imp);
868    
869        /* draw white line */
870        cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);
871        cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
872        cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/3);
873        cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_M);
874        cairo_rel_line_to (cr, 0,  OSD_SCALE_TICK);
875        cairo_rel_line_to (cr, width_metric, 0);
876        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);
883    
884        /* draw black line */
885        cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
886        cairo_set_line_width (cr, OSD_SCALE_FONT_SIZE/6);
887        cairo_move_to (cr, OSD_SCALE_FONT_SIZE/6, OSD_SCALE_M);
888        cairo_rel_line_to (cr, 0,  OSD_SCALE_TICK);
889        cairo_rel_line_to (cr, width_metric, 0);
890        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);
897    
898        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)
904    {
905      osd_priv_t *priv = (osd_priv_t*)osd->priv;      osd_priv_t *priv = (osd_priv_t*)osd->priv;
906    
907  #ifndef OSD_COLOR  #ifndef OSD_COLOR
# Line 802  osd_render(osm_gps_map_osd_t *osd) { Line 986  osd_render(osm_gps_map_osd_t *osd) {
986  #ifdef OSD_SOURCE_SEL  #ifdef OSD_SOURCE_SEL
987      osd_render_source_sel(osd);      osd_render_source_sel(osd);
988  #endif  #endif
989    
990    #ifdef OSD_SCALE
991        osd_render_scale(osd);
992    #endif
993    
994    #ifdef OSD_CROSSHAIR
995        osd_render_crosshair(osd);
996    #endif
997  }  }
998    
999  static void  static void
# Line 823  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1015  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1015                                             OSD_S_W+2, OSD_S_H+2);                                             OSD_S_W+2, OSD_S_H+2);
1016  #endif  #endif
1017    
1018    #ifdef OSD_SCALE
1019            priv->scale =
1020                cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1021                                           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
1030    
1031          /* ... and render it */          /* ... and render it */
1032          osd_render(osd);          osd_render(osd);
1033      }      }
# Line 862  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 1067  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
1067      cairo_paint(cr);      cairo_paint(cr);
1068  #endif  #endif
1069    
1070    #ifdef OSD_SCALE
1071        x =  OSD_X;
1072        y = -OSD_Y;
1073        if(x < 0) x += osd->widget->allocation.width - OSD_SCALE_W;
1074        if(y < 0) y += osd->widget->allocation.height - OSD_SCALE_H;
1075    
1076        cairo_set_source_surface(cr, priv->scale, x, y);
1077        cairo_paint(cr);
1078    #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 881  osd_free(osm_gps_map_osd_t *osd) Line 1104  osd_free(osm_gps_map_osd_t *osd)
1104           cairo_surface_destroy(priv->map_source);           cairo_surface_destroy(priv->map_source);
1105  #endif  #endif
1106    
1107    #ifdef OSD_SCALE
1108        if (priv->scale)
1109             cairo_surface_destroy(priv->scale);
1110    #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.89  
changed lines
  Added in v.105