URI: 
       half_block.rs - icy_draw - [fork] icy_draw is the successor to mystic draw.
  HTML git clone https://git.drkhsh.at/icy_draw.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
       ---
       half_block.rs (4252B)
       ---
            1 use crate::{AttributedChar, Buffer, Position, TextAttribute};
            2 
            3 pub(crate) const FULL_BLOCK: char = 219 as char;
            4 pub(crate) const HALF_BLOCK_TOP: char = 223 as char;
            5 pub(crate) const HALF_BLOCK_BOTTOM: char = 220 as char;
            6 
            7 pub(crate) struct HalfBlock {
            8     pub upper_block_color: u32,
            9     pub lower_block_color: u32,
           10     pub is_top: bool,
           11 }
           12 
           13 impl HalfBlock {
           14     pub fn from(buf: &Buffer, block: AttributedChar, pos: Position) -> Self {
           15         let is_top = pos.y % 2 == 0;
           16 
           17         let Some(font) = buf.get_font(block.get_font_page()) else {
           18             return Self {
           19                 upper_block_color: block.attribute.get_background(),
           20                 lower_block_color: block.attribute.get_background(),
           21                 is_top,
           22             };
           23         };
           24 
           25         let Some(glyph) = font.get_glyph(block.ch) else {
           26             return Self {
           27                 upper_block_color: block.attribute.get_background(),
           28                 lower_block_color: block.attribute.get_background(),
           29                 is_top,
           30             };
           31         };
           32 
           33         let mut upper = 0;
           34         let mut lower = 0;
           35         for i in 0..(glyph.data.len() / 2) {
           36             upper += glyph.data[i].count_ones() as i32;
           37             lower += glyph.data[glyph.data.len() / 2 + i].count_ones() as i32;
           38         }
           39         let upper_block_color = if upper > font.size.width * font.size.height / 4 {
           40             block.attribute.get_foreground()
           41         } else {
           42             block.attribute.get_background()
           43         };
           44         let lower_block_color = if lower > font.size.width * font.size.height / 4 {
           45             block.attribute.get_foreground()
           46         } else {
           47             block.attribute.get_background()
           48         };
           49 
           50         Self {
           51             upper_block_color,
           52             lower_block_color,
           53             is_top,
           54         }
           55     }
           56 }
           57 
           58 pub fn get_halfblock(buf: &Buffer, cur_char: AttributedChar, pos: Position, color: u32, transparent_color: bool) -> AttributedChar {
           59     let half_block = HalfBlock::from(buf, cur_char, pos);
           60     let transparent_color = cur_char.is_transparent() && transparent_color;
           61 
           62     let ch = if (half_block.is_top && half_block.lower_block_color == color) || (!half_block.is_top && half_block.upper_block_color == color) {
           63         AttributedChar::new(FULL_BLOCK, TextAttribute::new(color, 0))
           64     } else if half_block.is_top {
           65         AttributedChar::new(
           66             HALF_BLOCK_TOP,
           67             TextAttribute::new(
           68                 color,
           69                 if transparent_color {
           70                     TextAttribute::TRANSPARENT_COLOR
           71                 } else {
           72                     half_block.lower_block_color
           73                 },
           74             ),
           75         )
           76     } else {
           77         AttributedChar::new(
           78             HALF_BLOCK_BOTTOM,
           79             TextAttribute::new(
           80                 color,
           81                 if transparent_color {
           82                     TextAttribute::TRANSPARENT_COLOR
           83                 } else {
           84                     half_block.upper_block_color
           85                 },
           86             ),
           87         )
           88     };
           89 
           90     optimize_block(ch)
           91 }
           92 
           93 fn flip_colors(attribute: TextAttribute) -> TextAttribute {
           94     let mut result = attribute;
           95     result.set_foreground(attribute.get_background());
           96     result.set_background(attribute.get_foreground());
           97     result
           98 }
           99 
          100 fn optimize_block(mut block: AttributedChar) -> AttributedChar {
          101     if block.attribute.get_foreground() == 0 {
          102         if block.attribute.get_background() == 0 || block.ch == FULL_BLOCK {
          103             block.ch = ' ';
          104             return block;
          105         }
          106         match block.ch {
          107             HALF_BLOCK_BOTTOM => {
          108                 return AttributedChar::new(HALF_BLOCK_TOP, flip_colors(block.attribute));
          109             }
          110             HALF_BLOCK_TOP => {
          111                 return AttributedChar::new(HALF_BLOCK_BOTTOM, flip_colors(block.attribute));
          112             }
          113             _ => {}
          114         }
          115     } else if block.attribute.get_foreground() < 8 && block.attribute.get_background() >= 8 {
          116         match block.ch {
          117             HALF_BLOCK_BOTTOM => {
          118                 return AttributedChar::new(HALF_BLOCK_TOP, flip_colors(block.attribute));
          119             }
          120             HALF_BLOCK_TOP => {
          121                 return AttributedChar::new(HALF_BLOCK_BOTTOM, flip_colors(block.attribute));
          122             }
          123             _ => {}
          124         }
          125     }
          126     block
          127 }