font-explorer/src/writer/svg.rs

91 lines
2 KiB
Rust
Raw Normal View History

2025-03-03 12:18:52 +00:00
use std::{fs::File, io::{BufWriter, Write}};
use crate::font::{GlyphHeader, GlyphPoint};
use super::Visitor;
pub struct SvgWriter {
first_point: bool,
2025-03-03 16:21:55 +00:00
last_on_curve: bool,
final_point: Option<(i32, i32)>,
final_control: Option<(i32, i32)>,
2025-03-03 12:18:52 +00:00
writer: BufWriter<File>
}
impl SvgWriter {
pub fn new(file: File) -> Self {
SvgWriter {
first_point: true,
2025-03-03 16:21:55 +00:00
last_on_curve: false,
final_control: None,
final_point: None,
2025-03-03 12:18:52 +00:00
writer: BufWriter::new(file)
}
}
}
impl Visitor for SvgWriter {
fn write_prefix(&mut self, header: &GlyphHeader) {
write!(
self.writer,
"<svg width=\"1000\" height=\"1000\" viewBox=\"{} {} {} {}\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"",
2025-03-03 16:21:55 +00:00
header.xmin, -header.ymax,
2025-03-03 12:18:52 +00:00
header.xmax - header.xmin,
header.ymax - header.ymin
);
}
fn write_point(&mut self, point: &GlyphPoint) {
2025-03-03 16:21:55 +00:00
if self.final_point.is_none() && point.on_curve {
self.final_point = Some((point.x, point.y));
2025-03-03 12:18:52 +00:00
}
2025-03-03 16:21:55 +00:00
if self.first_point && self.final_control.is_none() && !point.on_curve {
self.final_control = Some((point.x, point.y));
}
if self.first_point {
if !point.on_curve {
return;
}
write!(self.writer, "M{} {} ", point.x, -point.y);
self.first_point = false;
self.last_on_curve = true;
return;
}
let prefix = if point.on_curve { if self.last_on_curve { "L" } else { "" } } else { "Q" };
self.last_on_curve = point.on_curve;
2025-03-03 12:18:52 +00:00
write!(
self.writer,
"{prefix}{} {} ",
2025-03-03 16:21:55 +00:00
point.x, -point.y
2025-03-03 12:18:52 +00:00
);
2025-03-03 16:21:55 +00:00
if point.is_endpoint {
if let Some(final_control) = self.final_control {
if let Some(final_point) = self.final_point {
write!(self.writer, "Q{} {} {} {} ", final_control.0, -final_control.1, final_point.0, -final_point.1);
} else {
write!(self.writer, "Z ");
}
} else {
write!(self.writer, "Z ");
}
self.final_point = None;
self.final_control = None;
}
self.first_point = point.is_endpoint;
2025-03-03 12:18:52 +00:00
}
fn write_suffix(&mut self) {
write!(
self.writer,
"\" style=\"fill:none; stroke:black; stroke-width:3;\" /></svg>"
);
}
}