use std::fs::{self,OpenOptions}; use std::process::Command; use std::string::ToString; use std::io::Write; fn main() { let mut c_constants = Vec::new(); let mut c_table = Vec::new(); for entry in fs::read_dir(".").unwrap() { let entry = entry.unwrap(); let path = entry.path(); if !path.display().to_string().ends_with(".ico") { continue; } let name = path.file_stem().unwrap().to_str().unwrap(); Command::new("/bin/convert").arg(&path).arg("./tmp.xbm").output().unwrap(); let content = fs::read_to_string("./tmp.xbm").unwrap(); println!("\n------------------------------------------------------------------------\n"); println!("{}", content); let mut lines = content.lines(); let l1 = lines.nth(0).unwrap(); let l2 = lines.nth(0).unwrap(); let w : usize = l1[l1.find("width").unwrap()+6..].parse().unwrap(); let h : usize = l2[l2.find("height").unwrap()+7..].parse().unwrap(); let a = content.find('{').unwrap() + 1; let b = content.find('}').unwrap(); let bytes = &content[a..b].trim(); let bytes = bytes.split(",") .map(|s| s.trim()) .filter(|s| !s.is_empty()) .map(|s| ! u8::from_str_radix(&s[2..], 16).unwrap()) .collect::>(); print!("---SOURCE--\n"); for y in 0..h { for x in 0..(w-1)/8+1 { for xx in 0..8 { if (bytes[y*(((w-1)/8+1)) + x] & (1u8 << xx)) != 0 { print!("█"); } else { print!("·"); } } } print!("\n"); } println!("---\n"); println!("name {},\nw {} h {},\nbytes {}", name, w, h, bytes.iter().map(|c| format!("{:#04x}", c)).collect::>().join(", ")); let bit_xy = |x : usize, y : usize| { let xx = x / 8; let nthbit = x % 8; let n = y*((w-1)/8+1) + xx; if n >= bytes.len() { 0u8 } else { let r = ((bytes[n] & (1 << nthbit)) >> nthbit) as u8; r } }; let result_cols = w; let result_rows = ((h-1)/8)+1; let mut result = Vec::new(); for y in 0..result_rows { for x in 0..result_cols { let mut buf = 0u8; for yy in 0..8 { buf |= bit_xy(x, y * 8 + yy) << yy; } result.push(buf); } } //println!("final bytes {}", result.iter().map(|c| format!("{:#04x}", c)).collect::>().join(", ")); let mut render = String::new(); print!("---\n"); for y in 0..result_rows { for yy in 0..8 { if y*8+yy >= h { break; } render.push_str("// "); for x in 0..result_cols { if (result[y*result_cols + x] & (1u8 << yy)) != 0 { print!("█"); render.push_str("█"); } else { print!("·"); render.push_str("·"); } } if yy == 7 { print!("/ end of byte row"); } render.push_str("\n"); print!("\n"); } } println!("---\n"); fn testchar(c : char) -> bool { c.is_alphanumeric() || c=='_' } let mut name = name.replace(|c:char|!testchar(c), "_"); if !name.starts_with(testchar) { name = format!("_{}", name); } c_constants.push(format!("\n/* {}x{}: {} */\n{}static const uint8_t G_{}_BYTES[] = {{ {} }};", w,h, name, render, name.to_uppercase(), result.iter().map(|c| format!("{:#04x}", c)).collect::>().join(", ") )); c_table.push(format!("{{ .name=\"{}\", .width={}, .height={}, .bytes=G_{}_BYTES }}", name, w, h, name.to_uppercase() )); } let c_source = format!(r##"#include "bitmaps.h" #include #include {} static const struct BitmapImage bitmaps[] = {{ {}, {{}} }}; const struct BitmapImage *Bitmap_Get(const char *name) {{ const struct BitmapImage *ptr = &bitmaps[0]; while (ptr->name) {{ if (0 == strcmp(ptr->name, name)) {{ return ptr; }} ptr++; }} return NULL; }} "##, c_constants.join("\n"), c_table.join(",\n ") ); let mut f = OpenOptions::new().write(true).create(true).truncate(true).open("./bitmaps.c").unwrap(); f.write(c_source.as_bytes()).unwrap(); let _ = fs::remove_file("./tmp.xbm"); }