mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 17:32:42 -06:00
Merge main into feat/character-anti-aliasing-method-r
This commit is contained in:
@@ -563,17 +563,25 @@ mod tests {
|
||||
fn the_ink_table_matches_the_profile() {
|
||||
let cms = cms::active();
|
||||
let lut = InkLut::build(&cms);
|
||||
let mut worst = 0.0f32;
|
||||
let (mut worst, mut worst_dark) = (0.0f32, 0.0f32);
|
||||
// Between the grid points (where interpolation errs most) and on them.
|
||||
for i in 0..=20 {
|
||||
for j in 0..=20 {
|
||||
let inks = [i as f32 / 20.0, j as f32 / 20.0, ((i * 7 + j * 3) % 21) as f32 / 20.0, ((i + j * 5) % 21) as f32 / 20.0];
|
||||
let (a, b) = (lut.apply(inks), cms.cmyk_to_srgb(inks, false));
|
||||
worst = worst.max((0..3).map(|c| (a[c] - b[c]).abs()).fold(0.0, f32::max));
|
||||
let err = (0..3).map(|c| (a[c] - b[c]).abs()).fold(0.0, f32::max);
|
||||
// Builds darker than the press's black point clip at 0 in one or more XYZ channels,
|
||||
// so the grid interpolates across that clip in the darkest levels.
|
||||
if b.iter().all(|v| *v < 0.05) {
|
||||
worst_dark = worst_dark.max(err);
|
||||
} else {
|
||||
worst = worst.max(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Within two 8-bit levels: far below a visible difference.
|
||||
assert!(worst * 255.0 < 2.5, "worst error {} levels", worst * 255.0);
|
||||
assert!(worst_dark * 255.0 < 5.0, "worst error near black {} levels", worst_dark * 255.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -119,6 +119,25 @@ fn variable_font_settings_are_not_highlighted_as_substituted_glyphs() {
|
||||
assert!(g.alternate_glyphs(&t).elements().is_empty());
|
||||
}
|
||||
|
||||
/// Type in a composite font draws each class of character in its part's face, which is not a
|
||||
/// substitute: Document Setup's highlight of substituted glyphs leaves it alone.
|
||||
#[test]
|
||||
fn composite_font_parts_are_not_highlighted_as_substituted_glyphs() {
|
||||
use vectorcraft_doc::{CompositeFont, CompositePart, CompositeParts};
|
||||
let _adding = adding_fonts();
|
||||
let db = vectorcraft_text::FontDb::global();
|
||||
let mut parts = CompositeParts::all(CompositePart::new("Source Sans 3", "Regular"));
|
||||
parts.roman = CompositePart::new("JetBrains Mono", "Regular");
|
||||
parts.numerals = CompositePart::new("Inter", "Regular");
|
||||
db.set_composite_font(&CompositeFont { name: "CF Highlight".into(), parts });
|
||||
let style = CharStyle { size: 40.0, font_family: "CF Highlight".into(), ..Default::default() };
|
||||
let t = TextObject::point(Point::new(10.0, 60.0), "Ab12", style);
|
||||
let g = text_geom(&t);
|
||||
db.remove_composite_font("CF Highlight");
|
||||
assert!(!g.all.elements().is_empty());
|
||||
assert!(g.substituted_glyphs.elements().is_empty() && g.substituted_fonts.elements().is_empty());
|
||||
}
|
||||
|
||||
/// Type at 80% opacity, in Multiply and with a drop shadow redraws in a font that becomes
|
||||
/// available: the glyph geometry kept for it is laid out again.
|
||||
#[test]
|
||||
|
||||
@@ -191,7 +191,14 @@ pub(crate) fn text_geom_snapped(t: &TextObject, snap: Option<Affine>) -> TextGeo
|
||||
if let Some(art) = g.placed_colour(Affine::IDENTITY) {
|
||||
colours.push((g.run, Arc::new(art)));
|
||||
}
|
||||
let Some(&(missing, face)) = faces.get(g.run) else { continue };
|
||||
let Some(&(mut missing, mut face)) = faces.get(g.run) else { continue };
|
||||
// Type in a composite font: each character's face is its class's part's.
|
||||
if let Some(r) = t.runs.get(g.run)
|
||||
&& let Some(c) = plain.get(g.byte..).and_then(|s| s.chars().next())
|
||||
&& let Some((m, f)) = db.composite_face(&r.style.font_family, c)
|
||||
{
|
||||
(missing, face) = (m, Some(f));
|
||||
}
|
||||
let Some(line) = layout.lines.get(g.line) else { continue };
|
||||
let mut cell = Rect::new(g.origin.x, g.origin.y - line.ascent, g.origin.x + g.advance, g.origin.y + line.descent).to_path(0.1);
|
||||
cell.apply_affine(Affine::rotate_about(g.angle, g.origin));
|
||||
|
||||
Reference in New Issue
Block a user