use crate::errors::Result;
use crate::geometry::{LabelMm, SafeArea};
use crate::image_encode;
use crate::types::{Density, Rotation, Threshold};
use std::path::Path;
use tracing::info;
pub fn compose_for_label(
path: &Path,
opts: &PrintOptions,
max_width_px: u32,
pixels_per_mm: f64,
) -> Result<image::DynamicImage> {
let mut img = image_encode::rotate(image::open(path)?, opts.rotate);
if opts.trim {
img = image_encode::trim_for_print(img, opts.threshold.get(), opts.dither);
}
match opts.label.map(|l| l.to_pixels(max_width_px, pixels_per_mm)) {
Some(lp) => {
info!(
width_px = lp.width_px,
height_px = lp.height_px,
width_mm = lp.mm(pixels_per_mm).width_mm,
height_mm = lp.mm(pixels_per_mm).height_mm,
max_w = max_width_px,
fill = opts.fill,
margin_px = opts.margin_px,
dither = opts.dither,
safe_bottom = opts.safe.bottom,
"label canvas"
);
img = if opts.fill {
image_encode::fill_label(img, lp, opts.safe, opts.margin_px)
} else {
image_encode::contain_label(img, lp, opts.safe, opts.margin_px)
}?;
}
None if opts.fit => img = image_encode::fit_width(img, max_width_px),
None => {}
}
Ok(img)
}
#[derive(Debug, Clone)]
pub struct PrintOptions {
pub density: Density,
pub rotate: Rotation,
pub threshold: Threshold,
pub fit: bool,
pub label: Option<LabelMm>,
pub fill: bool,
pub margin_px: u32,
pub dither: bool,
pub safe: SafeArea,
pub trim: bool,
}
impl Default for PrintOptions {
fn default() -> Self {
Self {
density: Density::NORMAL,
rotate: Rotation::Deg0,
threshold: Threshold::DEFAULT,
fit: false,
label: None,
fill: true,
margin_px: 0,
dither: false,
safe: SafeArea::default(),
trim: true,
}
}
}