mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 16:33:22 -06:00
Swatches: swatch exchange (.ase) files open as swatch libraries
File › Open, Other Library… and the User Defined library folder read .ase files. Colors keep their model, global and spot colors stay global and spot, and color groups stay groups. The library readers take a file's bytes. On the web, File › Open passes a swatch library file to swatch.library.load as dataBase64 instead of as lossy UTF-8 text. Swatch and group names in a library are now unique, in .gpl files too. Add to Swatches puts each color group of a library into one document group when the document already has a swatch with the group's name. The library fuzz helpers fail when a command panics.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
//! Hand-written swatch exchange (`.ase`) files for swatch library tests: version 1.0, big-endian,
|
||||
//! with colors in each model and color type, and color groups.
|
||||
|
||||
/// One block of a swatch exchange file.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Block<'a> {
|
||||
/// A color group starts (its name).
|
||||
GroupStart(&'a str),
|
||||
/// The open color group ends.
|
||||
GroupEnd,
|
||||
/// A color: its name, model (`b"RGB "`, `b"CMYK"`, `b"LAB "` or `b"Gray"`), components and
|
||||
/// color type (0 global, 1 spot, 2 process).
|
||||
Color(&'a str, &'a [u8; 4], &'a [f32], u16),
|
||||
}
|
||||
|
||||
/// A name: a `u16` count of UTF-16 code units, the terminating zero included, then the units.
|
||||
fn name(out: &mut Vec<u8>, name: &str) {
|
||||
let units: Vec<u16> = name.encode_utf16().chain([0]).collect();
|
||||
out.extend(u16::try_from(units.len()).unwrap().to_be_bytes());
|
||||
out.extend(units.iter().flat_map(|u| u.to_be_bytes()));
|
||||
}
|
||||
|
||||
/// A swatch exchange file of `blocks`.
|
||||
pub fn ase(blocks: &[Block]) -> Vec<u8> {
|
||||
let mut out = b"ASEF\0\x01\0\0".to_vec();
|
||||
out.extend(u32::try_from(blocks.len()).unwrap().to_be_bytes());
|
||||
for b in blocks {
|
||||
let mut body = vec![];
|
||||
let kind: u16 = match b {
|
||||
Block::GroupStart(n) => {
|
||||
name(&mut body, n);
|
||||
0xC001
|
||||
}
|
||||
Block::GroupEnd => 0xC002,
|
||||
Block::Color(n, model, values, kind) => {
|
||||
name(&mut body, n);
|
||||
body.extend(*model);
|
||||
body.extend(values.iter().flat_map(|v| v.to_be_bytes()));
|
||||
body.extend(kind.to_be_bytes());
|
||||
0x0001
|
||||
}
|
||||
};
|
||||
out.extend(kind.to_be_bytes());
|
||||
out.extend(u32::try_from(body.len()).unwrap().to_be_bytes());
|
||||
out.extend(body);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// A library of four colors: "Sky" (global RGB) and "Ink" (spot CMYK), then the group "Neutrals"
|
||||
/// of the process colors "Mist" (Gray, 25% ink) and "Clay" (Lab 50, 20, −30).
|
||||
pub fn sample() -> Vec<u8> {
|
||||
ase(&[
|
||||
Block::Color("Sky", b"RGB ", &[0.0, 0.5, 1.0], 0),
|
||||
Block::Color("Ink", b"CMYK", &[1.0, 0.5, 0.0, 0.2], 1),
|
||||
Block::GroupStart("Neutrals"),
|
||||
Block::Color("Mist", b"Gray", &[0.75], 2),
|
||||
Block::Color("Clay", b"LAB ", &[0.5, 20.0, -30.0], 2),
|
||||
Block::GroupEnd,
|
||||
])
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
//! - [`raster`]: rendering helpers and image comparison with a perceptual tolerance.
|
||||
//! - [`geom`]: geometry assertions (approximate equality, curve sampling, Hausdorff distance).
|
||||
//! - [`pdf`]: hand-written PDF files (page boxes, colour spaces, encryption) for import tests.
|
||||
//! - [`ase`]: hand-written swatch exchange (`.ase`) files for swatch library tests.
|
||||
//!
|
||||
//! This crate may only be used as a dev-dependency (enforced by `cargo xtask layers`).
|
||||
// Test support only (a dev-dependency of every crate that uses it): a failed setup or assertion
|
||||
@@ -18,6 +19,7 @@
|
||||
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
pub mod ase;
|
||||
pub mod fixtures;
|
||||
pub mod geom;
|
||||
pub mod invariants;
|
||||
|
||||
Reference in New Issue
Block a user