This commit is contained in:
2025-07-18 16:36:13 +02:00
parent 33f577718e
commit bd3cc2e612
2 changed files with 49 additions and 39 deletions

View File

@@ -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

View File

@@ -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