use pdfrum_common::kurbo::{Affine, Point, Rect};
use pdfrum_object::fmt_number;
pub fn write_float(out: &mut String, value: f32) {
out.push_str(&fmt_number(value));
}
pub fn write_matrix(out: &mut String, m: Affine) {
let c = m.as_coeffs();
for (i, v) in c.iter().enumerate() {
if i > 0 {
out.push(' ');
}
#[expect(
clippy::cast_possible_truncation,
reason = "PDF numbers are f32; the geometry vocabulary is f64"
)]
write_float(out, *v as f32);
}
}
pub fn write_point(out: &mut String, p: Point) {
#[expect(
clippy::cast_possible_truncation,
reason = "PDF numbers are f32; the geometry vocabulary is f64"
)]
{
write_float(out, p.x as f32);
out.push(' ');
write_float(out, p.y as f32);
}
}
pub fn write_rect(out: &mut String, r: Rect) {
#[expect(
clippy::cast_possible_truncation,
reason = "PDF numbers are f32; the geometry vocabulary is f64"
)]
{
write_float(out, r.x0 as f32);
out.push(' ');
write_float(out, r.y0 as f32);
out.push(' ');
write_float(out, (r.x1 - r.x0) as f32);
out.push(' ');
write_float(out, (r.y1 - r.y0) as f32);
}
}
#[cfg(test)]
mod tests {
use super::{write_float, write_matrix, write_point, write_rect};
use pdfrum_common::kurbo::{Affine, Point, Rect};
fn s(f: impl FnOnce(&mut String)) -> String {
let mut out = String::new();
f(&mut out);
out
}
#[test]
fn floats_carry_no_space_and_no_sign() {
assert_eq!(s(|o| write_float(o, 0.0)), "0");
assert_eq!(s(|o| write_float(o, 1.0)), "1");
assert_eq!(s(|o| write_float(o, -1.0)), "-1");
assert_eq!(s(|o| write_float(o, 0.5)), ".5");
assert_eq!(s(|o| write_float(o, -0.5)), "-.5");
assert_eq!(s(|o| write_float(o, 10.5)), "10.5");
}
#[test]
fn matrix_is_six_space_separated_numbers() {
assert_eq!(
s(|o| write_matrix(o, Affine::new([1.0, 0.0, 0.0, 1.0, 10.5, 20.25]))),
"1 0 0 1 10.5 20.25"
);
}
#[test]
fn point_is_two_numbers() {
assert_eq!(s(|o| write_point(o, Point::new(1.0, 2.5))), "1 2.5");
}
#[test]
fn rect_is_left_bottom_width_height() {
assert_eq!(
s(|o| write_rect(o, Rect::new(1.0, 2.0, 10.0, 20.0))),
"1 2 9 18"
);
}
#[test]
fn extreme_magnitudes_stay_positional() {
assert_eq!(s(|o| write_float(o, 0.000_001)), ".000001");
assert_eq!(s(|o| write_float(o, 1_000_000_000_000.0)), "1000000000000");
assert_eq!(s(|o| write_float(o, 0.5)), ".5");
}
}