@@ -20,12 +20,12 @@ use embassy_nrf::peripherals::{P0_02, P0_03, P0_28, P1_10, P1_11, P1_13, SPI3};
2020use embassy_nrf:: spim:: { self , Spim } ;
2121use embassy_nrf:: { interrupt, Peri } ;
2222use embassy_time:: { Delay , Duration , Instant , Timer } ;
23- use embedded_graphics:: mono_font:: ascii:: { FONT_6X10 , FONT_9X15 , FONT_9X18_BOLD } ;
23+ use embedded_graphics:: mono_font:: ascii:: { FONT_6X10 , FONT_9X15 } ;
2424use embedded_graphics:: mono_font:: MonoTextStyle ;
2525use embedded_graphics:: pixelcolor:: Rgb565 ;
2626use embedded_graphics:: prelude:: * ;
2727use embedded_graphics:: primitives:: {
28- PrimitiveStyle , PrimitiveStyleBuilder , Rectangle , RoundedRectangle ,
28+ Line , PrimitiveStyle , PrimitiveStyleBuilder , Rectangle , RoundedRectangle ,
2929} ;
3030use embedded_graphics:: text:: { Alignment , Baseline , Text , TextStyleBuilder } ;
3131use embedded_hal_bus:: spi:: { ExclusiveDevice , NoDelay } ;
@@ -65,6 +65,10 @@ const SAFE_W: u32 = SCREEN_W as u32 - (SAFE_X as u32 * 2);
6565const PANEL_RADIUS : u32 = 12 ;
6666const CHIP_RADIUS : u32 = 8 ;
6767const BAR_RADIUS : u32 = 5 ;
68+ const LAYER_TITLE_W : i32 = 12 ;
69+ const LAYER_TITLE_H : i32 = 24 ;
70+ const LAYER_TITLE_GAP : i32 = 1 ;
71+ const LAYER_TITLE_STROKE : u32 = 2 ;
6872
6973const COL_BG : Rgb565 = Rgb565 :: new ( 1 , 3 , 5 ) ;
7074const COL_FG : Rgb565 = Rgb565 :: new ( 30 , 61 , 30 ) ;
@@ -668,7 +672,6 @@ impl DisplayRenderer<Rgb565> for QubeStatusRenderer {
668672 let small = MonoTextStyle :: new ( & FONT_6X10 , COL_MUTED ) ;
669673 let small_dim = MonoTextStyle :: new ( & FONT_6X10 , COL_DIM ) ;
670674 let body = MonoTextStyle :: new ( & FONT_9X15 , COL_FG ) ;
671- let layer_title = MonoTextStyle :: new ( & FONT_9X18_BOLD , COL_FG ) ;
672675 let body_muted = MonoTextStyle :: new ( & FONT_9X15 , COL_MUTED ) ;
673676 let body_accent = MonoTextStyle :: new ( & FONT_9X15 , COL_ACCENT ) ;
674677 let body_amber = MonoTextStyle :: new ( & FONT_9X15 , COL_AMBER ) ;
@@ -734,8 +737,7 @@ impl DisplayRenderer<Rgb565> for QubeStatusRenderer {
734737 let _ = write ! ( & mut s, "LAYER {}" , ctx. layer) ;
735738 let _ =
736739 Text :: with_text_style ( & s, Point :: new ( SCREEN_W as i32 / 2 , 69 ) , small, tc) . draw ( display) ;
737- let _ = Text :: with_text_style ( name, Point :: new ( SCREEN_W as i32 / 2 , 92 ) , layer_title, tc)
738- . draw ( display) ;
740+ draw_vector_text_centered ( display, name, SCREEN_W as i32 / 2 , 101 , COL_FG ) ;
739741
740742 // Modifier chips.
741743 draw_panel ( display, SAFE_X , 138 , SAFE_W , 27 , COL_PANEL , COL_BORDER ) ;
@@ -846,6 +848,271 @@ fn draw_chip<D: DrawTarget<Color = Rgb565>>(
846848 Text :: with_text_style ( label, Point :: new ( x + w as i32 / 2 , y + 3 ) , text, tc) . draw ( display) ;
847849}
848850
851+ fn draw_vector_text_centered < D : DrawTarget < Color = Rgb565 > > (
852+ display : & mut D ,
853+ text : & str ,
854+ center_x : i32 ,
855+ center_y : i32 ,
856+ color : Rgb565 ,
857+ ) {
858+ let chars = text. chars ( ) . count ( ) as i32 ;
859+ if chars == 0 {
860+ return ;
861+ }
862+ let total_w = chars * LAYER_TITLE_W + ( chars - 1 ) * LAYER_TITLE_GAP ;
863+ let mut x = center_x - total_w / 2 ;
864+ let y = center_y - LAYER_TITLE_H / 2 ;
865+ for ch in text. chars ( ) {
866+ draw_vector_glyph ( display, ch, x, y, color) ;
867+ x += LAYER_TITLE_W + LAYER_TITLE_GAP ;
868+ }
869+ }
870+
871+ fn draw_vector_glyph < D : DrawTarget < Color = Rgb565 > > (
872+ display : & mut D ,
873+ ch : char ,
874+ x : i32 ,
875+ y : i32 ,
876+ color : Rgb565 ,
877+ ) {
878+ match ch {
879+ 'A' => {
880+ seg ( display, x, y, 1 , 14 , 3 , 0 , color) ;
881+ seg ( display, x, y, 9 , 14 , 7 , 0 , color) ;
882+ seg ( display, x, y, 3 , 0 , 7 , 0 , color) ;
883+ seg ( display, x, y, 2 , 7 , 8 , 7 , color) ;
884+ }
885+ 'B' => {
886+ seg ( display, x, y, 1 , 0 , 1 , 14 , color) ;
887+ seg ( display, x, y, 1 , 0 , 7 , 0 , color) ;
888+ seg ( display, x, y, 7 , 0 , 10 , 3 , color) ;
889+ seg ( display, x, y, 10 , 3 , 10 , 5 , color) ;
890+ seg ( display, x, y, 10 , 5 , 8 , 7 , color) ;
891+ seg ( display, x, y, 1 , 7 , 8 , 7 , color) ;
892+ seg ( display, x, y, 8 , 7 , 10 , 9 , color) ;
893+ seg ( display, x, y, 10 , 9 , 10 , 12 , color) ;
894+ seg ( display, x, y, 10 , 12 , 7 , 14 , color) ;
895+ seg ( display, x, y, 1 , 14 , 7 , 14 , color) ;
896+ }
897+ 'D' => {
898+ seg ( display, x, y, 1 , 0 , 1 , 14 , color) ;
899+ seg ( display, x, y, 1 , 0 , 7 , 0 , color) ;
900+ seg ( display, x, y, 7 , 0 , 10 , 3 , color) ;
901+ seg ( display, x, y, 10 , 3 , 10 , 11 , color) ;
902+ seg ( display, x, y, 10 , 11 , 7 , 14 , color) ;
903+ seg ( display, x, y, 1 , 14 , 7 , 14 , color) ;
904+ }
905+ 'E' => {
906+ seg ( display, x, y, 1 , 0 , 1 , 14 , color) ;
907+ seg ( display, x, y, 1 , 0 , 10 , 0 , color) ;
908+ seg ( display, x, y, 1 , 7 , 8 , 7 , color) ;
909+ seg ( display, x, y, 1 , 14 , 10 , 14 , color) ;
910+ }
911+ 'F' => {
912+ seg ( display, x, y, 1 , 0 , 1 , 14 , color) ;
913+ seg ( display, x, y, 1 , 0 , 10 , 0 , color) ;
914+ seg ( display, x, y, 1 , 7 , 8 , 7 , color) ;
915+ }
916+ 'G' => {
917+ seg ( display, x, y, 10 , 1 , 3 , 1 , color) ;
918+ seg ( display, x, y, 3 , 1 , 1 , 4 , color) ;
919+ seg ( display, x, y, 1 , 4 , 1 , 11 , color) ;
920+ seg ( display, x, y, 1 , 11 , 3 , 14 , color) ;
921+ seg ( display, x, y, 3 , 14 , 10 , 14 , color) ;
922+ seg ( display, x, y, 10 , 14 , 10 , 8 , color) ;
923+ seg ( display, x, y, 10 , 8 , 6 , 8 , color) ;
924+ }
925+ 'J' => {
926+ seg ( display, x, y, 2 , 0 , 10 , 0 , color) ;
927+ seg ( display, x, y, 8 , 0 , 8 , 11 , color) ;
928+ seg ( display, x, y, 8 , 11 , 6 , 14 , color) ;
929+ seg ( display, x, y, 6 , 14 , 2 , 14 , color) ;
930+ seg ( display, x, y, 2 , 14 , 1 , 11 , color) ;
931+ }
932+ 'L' => {
933+ seg ( display, x, y, 1 , 0 , 1 , 14 , color) ;
934+ seg ( display, x, y, 1 , 14 , 10 , 14 , color) ;
935+ }
936+ 'M' => {
937+ seg ( display, x, y, 1 , 14 , 1 , 0 , color) ;
938+ seg ( display, x, y, 1 , 0 , 5 , 7 , color) ;
939+ seg ( display, x, y, 5 , 7 , 9 , 0 , color) ;
940+ seg ( display, x, y, 9 , 0 , 9 , 14 , color) ;
941+ }
942+ 'N' => {
943+ seg ( display, x, y, 1 , 14 , 1 , 0 , color) ;
944+ seg ( display, x, y, 1 , 0 , 10 , 14 , color) ;
945+ seg ( display, x, y, 10 , 14 , 10 , 0 , color) ;
946+ }
947+ 'P' => {
948+ seg ( display, x, y, 1 , 14 , 1 , 0 , color) ;
949+ seg ( display, x, y, 1 , 0 , 8 , 0 , color) ;
950+ seg ( display, x, y, 8 , 0 , 10 , 3 , color) ;
951+ seg ( display, x, y, 10 , 3 , 10 , 6 , color) ;
952+ seg ( display, x, y, 10 , 6 , 8 , 8 , color) ;
953+ seg ( display, x, y, 1 , 8 , 8 , 8 , color) ;
954+ }
955+ 'R' => {
956+ seg ( display, x, y, 1 , 14 , 1 , 0 , color) ;
957+ seg ( display, x, y, 1 , 0 , 8 , 0 , color) ;
958+ seg ( display, x, y, 8 , 0 , 10 , 3 , color) ;
959+ seg ( display, x, y, 10 , 3 , 10 , 6 , color) ;
960+ seg ( display, x, y, 10 , 6 , 8 , 8 , color) ;
961+ seg ( display, x, y, 1 , 8 , 8 , 8 , color) ;
962+ seg ( display, x, y, 6 , 8 , 10 , 14 , color) ;
963+ }
964+ 'S' => {
965+ seg ( display, x, y, 10 , 1 , 3 , 1 , color) ;
966+ seg ( display, x, y, 3 , 1 , 1 , 4 , color) ;
967+ seg ( display, x, y, 1 , 4 , 3 , 7 , color) ;
968+ seg ( display, x, y, 3 , 7 , 8 , 7 , color) ;
969+ seg ( display, x, y, 8 , 7 , 10 , 10 , color) ;
970+ seg ( display, x, y, 10 , 10 , 8 , 13 , color) ;
971+ seg ( display, x, y, 8 , 13 , 1 , 13 , color) ;
972+ }
973+ 'T' => {
974+ seg ( display, x, y, 1 , 0 , 10 , 0 , color) ;
975+ seg ( display, x, y, 5 , 0 , 5 , 14 , color) ;
976+ }
977+ 'U' => {
978+ seg ( display, x, y, 1 , 0 , 1 , 11 , color) ;
979+ seg ( display, x, y, 1 , 11 , 4 , 14 , color) ;
980+ seg ( display, x, y, 4 , 14 , 8 , 14 , color) ;
981+ seg ( display, x, y, 8 , 14 , 10 , 11 , color) ;
982+ seg ( display, x, y, 10 , 11 , 10 , 0 , color) ;
983+ }
984+ 'V' => {
985+ seg ( display, x, y, 1 , 0 , 5 , 14 , color) ;
986+ seg ( display, x, y, 5 , 14 , 10 , 0 , color) ;
987+ }
988+ 'Y' => {
989+ seg ( display, x, y, 1 , 0 , 5 , 7 , color) ;
990+ seg ( display, x, y, 10 , 0 , 5 , 7 , color) ;
991+ seg ( display, x, y, 5 , 7 , 5 , 14 , color) ;
992+ }
993+ '0' => {
994+ seg ( display, x, y, 3 , 0 , 8 , 0 , color) ;
995+ seg ( display, x, y, 8 , 0 , 10 , 3 , color) ;
996+ seg ( display, x, y, 10 , 3 , 10 , 11 , color) ;
997+ seg ( display, x, y, 10 , 11 , 8 , 14 , color) ;
998+ seg ( display, x, y, 8 , 14 , 3 , 14 , color) ;
999+ seg ( display, x, y, 3 , 14 , 1 , 11 , color) ;
1000+ seg ( display, x, y, 1 , 11 , 1 , 3 , color) ;
1001+ seg ( display, x, y, 1 , 3 , 3 , 0 , color) ;
1002+ }
1003+ '1' => {
1004+ seg ( display, x, y, 5 , 0 , 5 , 14 , color) ;
1005+ seg ( display, x, y, 3 , 3 , 5 , 0 , color) ;
1006+ seg ( display, x, y, 2 , 14 , 8 , 14 , color) ;
1007+ }
1008+ '2' => {
1009+ seg ( display, x, y, 2 , 1 , 8 , 1 , color) ;
1010+ seg ( display, x, y, 8 , 1 , 10 , 4 , color) ;
1011+ seg ( display, x, y, 10 , 4 , 1 , 14 , color) ;
1012+ seg ( display, x, y, 1 , 14 , 10 , 14 , color) ;
1013+ }
1014+ '3' => {
1015+ seg ( display, x, y, 2 , 1 , 8 , 1 , color) ;
1016+ seg ( display, x, y, 8 , 1 , 10 , 4 , color) ;
1017+ seg ( display, x, y, 6 , 7 , 10 , 7 , color) ;
1018+ seg ( display, x, y, 10 , 7 , 10 , 11 , color) ;
1019+ seg ( display, x, y, 10 , 11 , 8 , 14 , color) ;
1020+ seg ( display, x, y, 8 , 14 , 2 , 14 , color) ;
1021+ }
1022+ '4' => {
1023+ seg ( display, x, y, 9 , 0 , 9 , 14 , color) ;
1024+ seg ( display, x, y, 1 , 0 , 1 , 7 , color) ;
1025+ seg ( display, x, y, 1 , 7 , 10 , 7 , color) ;
1026+ }
1027+ '5' => {
1028+ seg ( display, x, y, 10 , 1 , 2 , 1 , color) ;
1029+ seg ( display, x, y, 2 , 1 , 2 , 7 , color) ;
1030+ seg ( display, x, y, 2 , 7 , 8 , 7 , color) ;
1031+ seg ( display, x, y, 8 , 7 , 10 , 10 , color) ;
1032+ seg ( display, x, y, 10 , 10 , 8 , 14 , color) ;
1033+ seg ( display, x, y, 8 , 14 , 1 , 14 , color) ;
1034+ }
1035+ '6' => {
1036+ seg ( display, x, y, 9 , 1 , 3 , 1 , color) ;
1037+ seg ( display, x, y, 3 , 1 , 1 , 5 , color) ;
1038+ seg ( display, x, y, 1 , 5 , 1 , 11 , color) ;
1039+ seg ( display, x, y, 1 , 11 , 3 , 14 , color) ;
1040+ seg ( display, x, y, 3 , 14 , 8 , 14 , color) ;
1041+ seg ( display, x, y, 8 , 14 , 10 , 11 , color) ;
1042+ seg ( display, x, y, 10 , 11 , 8 , 8 , color) ;
1043+ seg ( display, x, y, 8 , 8 , 1 , 8 , color) ;
1044+ }
1045+ '7' => {
1046+ seg ( display, x, y, 1 , 1 , 10 , 1 , color) ;
1047+ seg ( display, x, y, 10 , 1 , 4 , 14 , color) ;
1048+ }
1049+ '8' => {
1050+ seg ( display, x, y, 3 , 0 , 8 , 0 , color) ;
1051+ seg ( display, x, y, 8 , 0 , 10 , 3 , color) ;
1052+ seg ( display, x, y, 10 , 3 , 8 , 7 , color) ;
1053+ seg ( display, x, y, 8 , 7 , 10 , 11 , color) ;
1054+ seg ( display, x, y, 10 , 11 , 8 , 14 , color) ;
1055+ seg ( display, x, y, 8 , 14 , 3 , 14 , color) ;
1056+ seg ( display, x, y, 3 , 14 , 1 , 11 , color) ;
1057+ seg ( display, x, y, 1 , 11 , 3 , 7 , color) ;
1058+ seg ( display, x, y, 3 , 7 , 1 , 3 , color) ;
1059+ seg ( display, x, y, 1 , 3 , 3 , 0 , color) ;
1060+ seg ( display, x, y, 3 , 7 , 8 , 7 , color) ;
1061+ }
1062+ '9' => {
1063+ seg ( display, x, y, 8 , 14 , 10 , 10 , color) ;
1064+ seg ( display, x, y, 10 , 10 , 10 , 3 , color) ;
1065+ seg ( display, x, y, 10 , 3 , 8 , 0 , color) ;
1066+ seg ( display, x, y, 8 , 0 , 3 , 0 , color) ;
1067+ seg ( display, x, y, 3 , 0 , 1 , 3 , color) ;
1068+ seg ( display, x, y, 1 , 3 , 3 , 7 , color) ;
1069+ seg ( display, x, y, 3 , 7 , 10 , 7 , color) ;
1070+ }
1071+ '?' => {
1072+ seg ( display, x, y, 2 , 2 , 5 , 0 , color) ;
1073+ seg ( display, x, y, 5 , 0 , 9 , 2 , color) ;
1074+ seg ( display, x, y, 9 , 2 , 9 , 5 , color) ;
1075+ seg ( display, x, y, 9 , 5 , 5 , 8 , color) ;
1076+ dot ( display, x, y, 5 , 13 , color) ;
1077+ }
1078+ _ => { }
1079+ }
1080+ }
1081+
1082+ fn seg < D : DrawTarget < Color = Rgb565 > > (
1083+ display : & mut D ,
1084+ x : i32 ,
1085+ y : i32 ,
1086+ x0 : i32 ,
1087+ y0 : i32 ,
1088+ x1 : i32 ,
1089+ y1 : i32 ,
1090+ color : Rgb565 ,
1091+ ) {
1092+ let p0 = Point :: new ( x + x0 * LAYER_TITLE_W / 10 , y + y0 * LAYER_TITLE_H / 14 ) ;
1093+ let p1 = Point :: new ( x + x1 * LAYER_TITLE_W / 10 , y + y1 * LAYER_TITLE_H / 14 ) ;
1094+ let _ = Line :: new ( p0, p1)
1095+ . into_styled ( PrimitiveStyle :: with_stroke ( color, LAYER_TITLE_STROKE ) )
1096+ . draw ( display) ;
1097+ }
1098+
1099+ fn dot < D : DrawTarget < Color = Rgb565 > > (
1100+ display : & mut D ,
1101+ x : i32 ,
1102+ y : i32 ,
1103+ cx : i32 ,
1104+ cy : i32 ,
1105+ color : Rgb565 ,
1106+ ) {
1107+ let p = Point :: new (
1108+ x + cx * LAYER_TITLE_W / 10 - 1 ,
1109+ y + cy * LAYER_TITLE_H / 14 - 1 ,
1110+ ) ;
1111+ let _ = Rectangle :: new ( Point :: new ( p. x , p. y ) , Size :: new ( 3 , 3 ) )
1112+ . into_styled ( PrimitiveStyle :: with_fill ( color) )
1113+ . draw ( display) ;
1114+ }
1115+
8491116#[ derive( Clone , Copy ) ]
8501117enum BatReading {
8511118 Unknown ,
0 commit comments