mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 23:05:05 +00:00
HP-GL export: the writer refuses a bad curve tolerance or more than 255 pens
A tolerance outside 0.01 to 10 points, or one that is not finite, and a pen table of more than 255 colors are errors instead of being clamped or cut short. document.export already refuses both.
This commit is contained in:
@@ -142,9 +142,11 @@ impl Origin {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct HpglOptions {
|
||||
pub version: Version,
|
||||
/// How far a flattened curve may lie from the curve, points ([`TOLERANCE_RANGE`]).
|
||||
/// How far a flattened curve may lie from the curve, points ([`TOLERANCE_RANGE`]; a value
|
||||
/// outside it is an error).
|
||||
pub tolerance: f64,
|
||||
/// The pen table: pen 1's color first. Empty: a pen for each color the art draws in.
|
||||
/// The pen table: pen 1's color first, up to [`MAX_PENS`] (more is an error). Empty: a pen for
|
||||
/// each color the art draws in.
|
||||
pub pens: Vec<[u8; 3]>,
|
||||
pub origin: Origin,
|
||||
/// Draw each pen's paths nearest first, instead of in paint order.
|
||||
@@ -184,8 +186,13 @@ pub fn export_regions(doc: &Document, opts: &HpglOptions, regions: &[Rect]) -> R
|
||||
if regions.iter().any(|r| ![r.x0, r.y0, r.x1, r.y1].iter().all(|v| v.is_finite()) || r.width() <= 0.0 || r.height() <= 0.0) {
|
||||
return Err("the export region is empty".into());
|
||||
}
|
||||
let tolerance =
|
||||
if opts.tolerance.is_finite() { opts.tolerance.clamp(*TOLERANCE_RANGE.start(), *TOLERANCE_RANGE.end()) } else { DEFAULT_TOLERANCE };
|
||||
if !TOLERANCE_RANGE.contains(&opts.tolerance) {
|
||||
return Err("the curve tolerance must be from 0.01 to 10 points".into());
|
||||
}
|
||||
if opts.pens.len() > MAX_PENS {
|
||||
return Err("the pen table holds more than 255 pens".into());
|
||||
}
|
||||
let tolerance = opts.tolerance;
|
||||
// Layers the plot leaves out go first: baking can wrap one in art that would be drawn (its
|
||||
// crop marks).
|
||||
let shown = plotted(&doc.layers, false).map(|layers| {
|
||||
|
||||
@@ -441,6 +441,22 @@ fn an_empty_or_zero_length_plot_has_no_moves() {
|
||||
assert!(export(&d, &nan).is_err());
|
||||
}
|
||||
|
||||
/// A tolerance outside its range and a pen table of more than 255 pens are errors, not changed.
|
||||
#[test]
|
||||
fn bad_options_are_errors() {
|
||||
let d = three();
|
||||
for tolerance in [0.0, 0.009, 10.01, f64::NAN, f64::INFINITY] {
|
||||
let o = HpglOptions { tolerance, ..opts(&d) };
|
||||
assert_eq!(export(&d, &o).err().as_deref(), Some("the curve tolerance must be from 0.01 to 10 points"), "{tolerance}");
|
||||
}
|
||||
for tolerance in [0.01, 10.0] {
|
||||
assert!(export(&d, &HpglOptions { tolerance, ..opts(&d) }).is_ok(), "{tolerance}");
|
||||
}
|
||||
let o = HpglOptions { pens: vec![[0, 0, 0]; MAX_PENS + 1], ..opts(&d) };
|
||||
assert_eq!(export(&d, &o).err().as_deref(), Some("the pen table holds more than 255 pens"));
|
||||
assert!(export(&d, &HpglOptions { pens: vec![[0, 0, 0]; MAX_PENS], ..opts(&d) }).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn art_past_the_plotter_range_is_cut_off() {
|
||||
let d = doc_with(|d| vec![stroked(d, line((0.0, 50.0), (1e9, 50.0)), Color::BLACK)]);
|
||||
|
||||
Reference in New Issue
Block a user