works
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
00000000 00 00 00 00 00 00 00 00 18 18 18 18 18 00 18 00
|
||||
00000010 6c 6c 6c 00 00 00 00 00 6c 6c fe 6c fe 6c 6c 00
|
||||
00000020 18 3e 60 3c 06 7c 18 00 00 c6 cc 18 30 66 c6 00
|
||||
00000030 38 6c 38 76 dc cc 76 00 18 18 30 00 00 00 00 00
|
||||
00000040 0c 18 30 30 30 18 0c 00 30 18 0c 0c 0c 18 30 00
|
||||
00000050 00 66 3c ff 3c 66 00 00 00 18 18 7e 18 18 00 00
|
||||
00000060 00 00 00 00 18 18 30 00 00 00 00 7e 00 00 00 00
|
||||
00000070 00 00 00 00 00 18 18 00 06 0c 18 30 60 c0 80 00
|
||||
00000080 38 6c c6 c6 c6 6c 38 00 18 38 18 18 18 18 7e 00
|
||||
00000090 7c c6 06 1c 30 66 fe 00 7c c6 06 3c 06 c6 7c 00
|
||||
000000a0 1c 3c 6c cc fe 0c 1e 00 fe c0 fc 06 06 c6 7c 00
|
||||
000000b0 38 60 c0 fc c6 c6 7c 00 fe c6 0c 18 30 30 30 00
|
||||
000000c0 7c c6 c6 7c c6 c6 7c 00 7c c6 c6 7e 06 0c 78 00
|
||||
000000d0 00 18 18 00 00 18 18 00 00 18 18 00 00 18 18 30
|
||||
000000e0 0c 18 30 60 30 18 0c 00 00 00 7e 00 7e 00 00 00
|
||||
000000f0 30 18 0c 06 0c 18 30 00 7c c6 0c 18 18 00 18 00
|
||||
72
src/main.rs
72
src/main.rs
@@ -6,9 +6,11 @@ use std::thread;
|
||||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use hound::{WavSpec, WavWriter, SampleFormat};
|
||||
use image::{Rgba, RgbaImage};
|
||||
use rusttype::{Font, Scale, point};
|
||||
|
||||
// Simple 8x8 bitmap font implementation
|
||||
mod builtin_font {
|
||||
use image::{Rgba, RgbaImage};
|
||||
// Each character is 8 bytes (8x8 pixels)
|
||||
const FONT_DATA: &[u8] = include_bytes!("../font8x8_basic.bin");
|
||||
|
||||
@@ -18,9 +20,10 @@ mod builtin_font {
|
||||
y: u32,
|
||||
text: &str,
|
||||
color: Rgba<u8>,
|
||||
scale: u32, // scale factor for font size
|
||||
) {
|
||||
let char_width = 8;
|
||||
let char_height = 8;
|
||||
let char_width = 8u32;
|
||||
let char_height = 8u32;
|
||||
|
||||
for (i, c) in text.chars().enumerate() {
|
||||
let char_index = c as usize;
|
||||
@@ -28,15 +31,21 @@ mod builtin_font {
|
||||
continue;
|
||||
}
|
||||
|
||||
let font_data = &FONT_DATA[char_index * char_width..(char_index + 1) * char_width];
|
||||
let font_data = &FONT_DATA[char_index * char_width as usize..(char_index + 1) * char_width as usize];
|
||||
|
||||
for row in 0..char_height {
|
||||
for col in 0..char_width {
|
||||
if font_data[row as usize] & (1 << (7 - col)) != 0 {
|
||||
let px = x + (i as u32 * char_width) + col;
|
||||
let py = y + row;
|
||||
if px < image.width() && py < image.height() {
|
||||
image.put_pixel(px, py, color);
|
||||
let px = x + (i as u32 * char_width * scale) + col * scale;
|
||||
let py = y + row * scale;
|
||||
for dx in 0..scale {
|
||||
for dy in 0..scale {
|
||||
let fx = px + dx;
|
||||
let fy = py + dy;
|
||||
if fx < image.width() && fy < image.height() {
|
||||
image.put_pixel(fx, fy, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,6 +178,38 @@ impl Robot36EncoderApp {
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_callsign_with_rusttype(image: &mut RgbaImage, text: &str) {
|
||||
// Path to a common system font found on this system
|
||||
let font_data = std::fs::read("/usr/share/fonts/TTF/VictorMonoNerdFont-Thin.ttf")
|
||||
.expect("Failed to load system font");
|
||||
let font = Font::try_from_vec(font_data).expect("Error constructing Font");
|
||||
let scale = Scale::uniform(32.0); // Adjust size as needed
|
||||
let start = point(5.0, 32.0); // x, y baseline
|
||||
let color = Rgba([0u8, 0u8, 0u8, 255u8]);
|
||||
|
||||
// Draw each glyph
|
||||
let v_metrics = font.v_metrics(scale);
|
||||
let glyphs: Vec<_> = font.layout(text, scale, start).collect();
|
||||
for glyph in glyphs {
|
||||
if let Some(bb) = glyph.pixel_bounding_box() {
|
||||
glyph.draw(|gx, gy, gv| {
|
||||
let x = gx as i32 + bb.min.x;
|
||||
let y = gy as i32 + bb.min.y;
|
||||
if x >= 0 && y >= 0 && (x as u32) < image.width() && (y as u32) < image.height() {
|
||||
let alpha = (gv * 255.0) as u8;
|
||||
let pixel = image.get_pixel_mut(x as u32, y as u32);
|
||||
*pixel = Rgba([
|
||||
color[0],
|
||||
color[1],
|
||||
color[2],
|
||||
alpha,
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_image_impl(
|
||||
input_path: PathBuf,
|
||||
output_path: PathBuf,
|
||||
@@ -184,22 +225,7 @@ impl Robot36EncoderApp {
|
||||
|
||||
// Add callsign overlay if provided
|
||||
if !callsign.is_empty() {
|
||||
// Draw black background for text
|
||||
for y in 0..16 {
|
||||
for x in 0..(callsign.len() as u32 * 8).min(image.width()) {
|
||||
if x < image.width() && y < image.height() {
|
||||
image.put_pixel(x, y, Rgba([0u8, 0u8, 0u8, 200u8]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw text
|
||||
builtin_font::draw_text(
|
||||
&mut image,
|
||||
5, 5, // x, y position
|
||||
&callsign,
|
||||
Rgba([255u8, 255u8, 255u8, 255u8]), // white text
|
||||
);
|
||||
Self::draw_callsign_with_rusttype(&mut image, &callsign);
|
||||
}
|
||||
|
||||
// Calculate target size while maintaining aspect ratio
|
||||
|
||||
Reference in New Issue
Block a user