diff options
| author | xxanqw <[email protected]> | 2025-11-30 00:33:44 +0200 |
|---|---|---|
| committer | xxanqw <[email protected]> | 2025-11-30 00:33:44 +0200 |
| commit | 28e212e0ac79ce54526815437c2428deed252079 (patch) | |
| tree | 0810d463675ed07c6d82892ec5733947c6ec2d3f /src | |
| parent | 77d0b7659ca23881f3a867de10bf8fa7bbecfd41 (diff) | |
| download | mikusays-c-28e212e0ac79ce54526815437c2428deed252079.tar.gz mikusays-c-28e212e0ac79ce54526815437c2428deed252079.zip | |
Add color debugging feature and improve RGB to ANSI conversion
Diffstat (limited to 'src')
| -rw-r--r-- | src/color.rs | 45 | ||||
| -rw-r--r-- | src/main.rs | 62 |
2 files changed, 72 insertions, 35 deletions
diff --git a/src/color.rs b/src/color.rs index f0ab080..ba79353 100644 --- a/src/color.rs +++ b/src/color.rs @@ -375,47 +375,22 @@ fn rgb_to_ansi256(r: u8, g: u8, b: u8) -> u8 { } /// Convert RGB to ANSI 16 color code -fn rgb_to_ansi16(r: u8, g: u8, b: u8) -> u8 { - // Calculate brightness +pub(crate) fn rgb_to_ansi16(r: u8, g: u8, b: u8) -> u8 { + // Calculate brightness (perceived luminance) let brightness = (r as f32 * 0.299 + g as f32 * 0.587 + b as f32 * 0.114).round() as u8; - - // Determine if it's bright or dark let is_bright = brightness > 128; - // Determine base color - let base_color = if r > g && r > b { - // Red dominant - if r > 192 && g < 64 && b < 64 { - 1 // Red - } else if r > g && r > b { - 3 // Yellow - } else { - 7 // White - } - } else if g > r && g > b { - // Green dominant - if g > 192 && r < 64 && b < 64 { - 2 // Green - } else if g > b { - 3 // Yellow - } else { - 6 // Cyan - } - } else { - // Blue dominant - if b > 192 && r < 64 && g < 64 { - 4 // Blue - } else if b > r { - 6 // Cyan - } else { - 5 // Magenta - } - }; + // Determine base color using simple thresholding on each channel, producing an index 0..7 + let r_on = r > 128; + let g_on = g > 128; + let b_on = b > 128; + let base_idx = (r_on as u8) + (g_on as u8) * 2 + (b_on as u8) * 4; // 0..7 + // SGR color codes: 30..37 for normal, 90..97 for bright if is_bright { - base_color + 8 // Bright colors are 8-15 + 90 + base_idx } else { - base_color // Normal colors are 0-7 + 30 + base_idx } } diff --git a/src/main.rs b/src/main.rs index c50f37c..90fc061 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,6 +58,9 @@ pub struct Args { /// Disable all coloring (respects NO_COLOR environment variable) #[arg(long)] pub no_color: bool, + /// Print color detection/debug info and exit + #[arg(long)] + pub color_debug: bool, } #[derive(Debug)] @@ -69,6 +72,8 @@ pub struct ColorConfig { pub single_color: Option<Color>, pub gradient: Option<(Color, Color)>, pub color_cache: Vec<Color>, + pub ansi_enabled: bool, + pub debug: bool, } pub fn parse_color_args(args: &Args) -> Result<ColorConfig, Box<dyn Error>> { @@ -160,6 +165,12 @@ pub fn parse_color_args(args: &Args) -> Result<ColorConfig, Box<dyn Error>> { std::process::exit(1); } + // Determine if ANSI is enabled (Windows toggle helper) — don't enable if --no-color + #[cfg(windows)] + let ansi_enabled = !args.no_color && enable_windows_ansi(); + #[cfg(not(windows))] + let ansi_enabled = false; + Ok(ColorConfig { mode: color_mode, rainbow: args.rainbow, @@ -168,6 +179,8 @@ pub fn parse_color_args(args: &Args) -> Result<ColorConfig, Box<dyn Error>> { single_color, gradient, color_cache: Vec::new(), + ansi_enabled, + debug: args.color_debug, }) } @@ -492,6 +505,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { // Parse color-related arguments let mut color_config = parse_color_args(&args)?; + // If color debug is requested, print information and exit + if args.color_debug { + eprintln!("Color Debug: mode={:?}, ansi_enabled={}, rainbow={}, saturation={}, brightness={}", + color_config.mode, color_config.ansi_enabled, color_config.rainbow, color_config.saturation, color_config.brightness); + if let Some(single) = &color_config.single_color { + eprintln!("Single color: {:?}", single); + } + if let Some((start, end)) = &color_config.gradient { + eprintln!("Gradient: {:?} -> {:?}", start, end); + } + return Ok(()); + } + draw_miku_says(&text, style, &mut color_config)?; Ok(()) @@ -585,6 +611,7 @@ mod tests { color: None, gradient: None, no_color: false, + color_debug: false, }; let config = parse_color_args(&args).unwrap(); @@ -609,6 +636,7 @@ mod tests { color: None, gradient: None, no_color: true, + color_debug: false, }; let config = parse_color_args(&args).unwrap(); @@ -656,6 +684,8 @@ mod tests { single_color: None, gradient: None, color_cache: vec![Color::Hex("#000000".to_string())], // Pre-filled + ansi_enabled: false, + debug: false, }; // Test with 0 characters @@ -677,6 +707,8 @@ mod tests { single_color: None, gradient: None, color_cache: vec![Color::Hex("#000000".to_string())], // Pre-filled + ansi_enabled: false, + debug: false, }; let start = Color::Hex("#FF0000".to_string()); @@ -701,6 +733,8 @@ mod tests { single_color: None, gradient: None, color_cache: Vec::new(), + ansi_enabled: false, + debug: false, }; generate_rainbow_cache(&mut config, 10); @@ -713,6 +747,14 @@ mod tests { } #[test] + fn test_rgb_to_ansi16_mapping() { + // Validate mapping for basic colors + assert_eq!(crate::color::rgb_to_ansi16(255, 0, 0), 31); + assert_eq!(crate::color::rgb_to_ansi16(255, 255, 255), 97); + assert_eq!(crate::color::rgb_to_ansi16(0, 0, 0), 30); + } + + #[test] fn test_generate_gradient_cache() { let mut config = ColorConfig { mode: ColorMode::Truecolor, @@ -722,6 +764,8 @@ mod tests { single_color: None, gradient: None, color_cache: Vec::new(), + ansi_enabled: false, + debug: false, }; let start = Color::Hex("#FF0000".to_string()); // Red @@ -736,4 +780,22 @@ mod tests { let last_color = &config.color_cache[9]; assert_ne!(first_color, last_color); } + + #[test] + fn test_parse_color_debug_flag() { + let args = Args { + text: Some("test".to_string()), + style: None, + list: false, + rainbow: false, + saturation: 100, + brightness: 50, + color: None, + gradient: None, + no_color: false, + color_debug: true, + }; + let config = parse_color_args(&args).unwrap(); + assert!(config.debug); + } } |
