use super::*;
pub fn make_calibration_label(
label: LabelPx,
safe: SafeArea,
pixels_per_mm: f64,
font_path: Option<&std::path::Path>,
) -> Result<GrayImage> {
let mut img = crate::image_encode::calibration_pattern(label, Some(safe), pixels_per_mm);
let Ok(font) = load_font(font_path, None) else {
return Ok(img);
};
let scale = pixels_per_mm / crate::geometry::PX_PER_MM;
let size = (13.0 * scale) as f32;
let inset =
((crate::image_encode::CALIBRATION_RULER_MAJOR_PX + 4) as f64 * scale).round() as u32;
let height_mm = (f64::from(label.height_px) / pixels_per_mm).floor() as u32;
let mut number = core::fmt::NumBuffer::new();
for mm in (0..=height_mm).step_by(5) {
let y = (f64::from(mm) * pixels_per_mm).round() as u32;
if y >= label.height_px {
break;
}
let text = mm.format_into(&mut number);
let w = font.text_width(text, size);
if inset + w >= label.width_px - inset {
break; }
let baseline = y.max(size as u32) as f32 - 1.0;
font.draw_text(&mut img, inset as f32, baseline, text, size);
font.draw_text(
&mut img,
(label.width_px - inset - w) as f32,
baseline,
text,
size,
);
}
Ok(img)
}
pub fn boundary_range(label: LabelPx, pixels_per_mm: f64) -> std::ops::RangeInclusive<u32> {
let last = (f64::from(label.height_px) / pixels_per_mm)
.floor()
.max(1.0) as u32
- 1;
let first = last.saturating_sub(BOUNDARY_SPAN_MM - 1);
first..=last
}
pub fn make_boundary_label(
label: LabelPx,
pixels_per_mm: f64,
font_path: Option<&std::path::Path>,
) -> Result<GrayImage> {
let (w, h) = (label.width_px, label.height_px);
let mut img = GrayImage::from_pixel(w, h, Luma([255]));
let font = load_font(font_path, None)?;
let range = boundary_range(label, pixels_per_mm);
let steps = range.end() - range.start() + 1;
let slot = w / steps.max(1);
let bar_w = slot.saturating_sub(4).max(1);
let size = 12.0f32;
for (i, mm) in range.enumerate() {
let i = i as u32;
let y = (f64::from(mm) * pixels_per_mm).round() as u32;
let next_y = (f64::from(mm + 1) * pixels_per_mm).round() as u32;
if next_y > h {
break;
}
let x0 = i * slot;
for yy in y..next_y.min(h) {
for xx in x0..(x0 + bar_w).min(w) {
img.put_pixel(xx, yy, Luma([0]));
}
}
let baseline = y as f32 - 2.0;
if baseline > size {
font.draw_text(&mut img, x0 as f32, baseline, &mm.to_string(), size);
}
}
Ok(img)
}