You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.1 KiB
172 lines
5.1 KiB
5 years ago
|
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::<Vec<_>>();
|
||
|
|
||
|
|
||
|
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::<Vec<_>>().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::<Vec<_>>().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::<Vec<_>>().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 <stddef.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
{}
|
||
|
|
||
|
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;
|
||
|
}}
|
||
|
}}
|
||
|
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");
|
||
|
}
|