@@ -2,15 +2,32 @@ use std::io::Write;
22
33use super :: { Layout , BAR_W , GAP_W } ;
44
5- const VBLOCKS : [ char ; 9 ] =
6- [ ' ' , '▁' , '▂' , '▃' , '▄' , '▅' , '▆' , '▇' , '█' ] ;
5+ // Pre-encoded UTF-8 byte sequences for each block character.
6+ // Space is ASCII (1 byte); the 8 block elements are all 3-byte U+2580..U+2588.
7+ // Entries that are 1-byte sequences store the byte in index 0; the write path
8+ // selects the correct slice length via VBLOCKS_LEN.
9+ const VBLOCKS_ENCODED : [ [ u8 ; 3 ] ; 9 ] = [
10+ [ b' ' , 0 , 0 ] , // ' ' U+0020 1 byte
11+ [ 0xE2 , 0x96 , 0x81 ] , // '▁' U+2581
12+ [ 0xE2 , 0x96 , 0x82 ] , // '▂' U+2582
13+ [ 0xE2 , 0x96 , 0x83 ] , // '▃' U+2583
14+ [ 0xE2 , 0x96 , 0x84 ] , // '▄' U+2584
15+ [ 0xE2 , 0x96 , 0x85 ] , // '▅' U+2585
16+ [ 0xE2 , 0x96 , 0x86 ] , // '▆' U+2586
17+ [ 0xE2 , 0x96 , 0x87 ] , // '▇' U+2587
18+ [ 0xE2 , 0x96 , 0x88 ] , // '█' U+2588
19+ ] ;
20+
21+ const VBLOCKS_LEN : [ usize ; 9 ] = [ 1 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 ] ;
22+
23+ // Index of the full-block character (U+2588) in the table.
24+ const FULL_BLOCK : usize = 8 ;
725
826#[ inline]
927#[ allow( clippy:: cast_possible_truncation, clippy:: cast_sign_loss) ]
10- fn v_partial ( frac : f32 ) -> char {
28+ fn v_partial_idx ( frac : f32 ) -> usize {
1129 let f = frac. clamp ( 0.0 , 0.9999 ) ;
12- let idx = f. mul_add ( 8.0 , 0.5 ) . floor ( ) as usize ;
13- * VBLOCKS . get ( idx. min ( 8 ) ) . unwrap_or ( & ' ' )
30+ f. mul_add ( 8.0 , 0.5 ) . floor ( ) as usize
1431}
1532
1633#[ inline]
@@ -46,6 +63,8 @@ pub fn draw_blocks_vertical<W: Write>(
4663 w : u16 ,
4764 h : u16 ,
4865 lay : & Layout ,
66+ fulls : & mut [ usize ] ,
67+ fracs : & mut [ f32 ] ,
4968) -> std:: io:: Result < ( ) > {
5069 let rows = h. saturating_sub ( lay. top_pad ) as usize ;
5170 let cols = w
@@ -58,10 +77,10 @@ pub fn draw_blocks_vertical<W: Write>(
5877 let per = BAR_W + GAP_W ;
5978 let n = bars
6079 . len ( )
61- . min ( cols. checked_div ( per) . map_or ( 1 , |v| v. max ( 1 ) ) ) ;
80+ . min ( cols. checked_div ( per) . map_or ( 1 , |v| v. max ( 1 ) ) )
81+ . min ( fulls. len ( ) )
82+ . min ( fracs. len ( ) ) ;
6283
63- let mut fulls = vec ! [ 0usize ; n] ;
64- let mut fracs = vec ! [ 0f32 ; n] ;
6584 for i in 0 ..n {
6685 let height =
6786 bars. get ( i) . copied ( ) . unwrap_or ( 0.0 ) . clamp ( 0.0 , 1.0 )
@@ -81,20 +100,23 @@ pub fn draw_blocks_vertical<W: Write>(
81100
82101 for i in 0 ..n {
83102 let f_val = fulls. get ( i) . copied ( ) . unwrap_or ( 0 ) ;
84- let ch = if row < f_val {
85- '█'
103+ let idx = if row < f_val {
104+ FULL_BLOCK
86105 } else if row == f_val
87106 && fracs. get ( i) . copied ( ) . unwrap_or ( 0.0 ) > 0.0
88107 {
89- v_partial ( fracs. get ( i) . copied ( ) . unwrap_or ( 0.0 ) )
108+ v_partial_idx ( fracs. get ( i) . copied ( ) . unwrap_or ( 0.0 ) )
90109 } else {
91- ' '
110+ 0
92111 } ;
93112
113+ let enc = VBLOCKS_ENCODED
114+ . get ( idx)
115+ . unwrap_or ( & VBLOCKS_ENCODED [ 0 ] ) ;
116+ let len = VBLOCKS_LEN . get ( idx) . copied ( ) . unwrap_or ( 1 ) ;
117+ let bytes = enc. get ( ..len) . unwrap_or ( enc. as_slice ( ) ) ;
94118 for _ in 0 ..BAR_W {
95- out. write_all (
96- ch. encode_utf8 ( & mut [ 0 ; 4 ] ) . as_bytes ( ) ,
97- ) ?;
119+ out. write_all ( bytes) ?;
98120 }
99121 write_spaces ( out, GAP_W ) ?;
100122 }
0 commit comments