mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-14 22:25:44 +00:00
Cover metafile transform and pen paths
This commit is contained in:
1 parent
ec2937f298
commit
f78a805ac7
2 files changed
+54
No files matched your search
@@ -25,3 +25,6 @@ skrifa = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
vello_cpu = { workspace = true, features = ["multithreading"] }
|
||||
|
||||
[dev-dependencies]
|
||||
craft-metafile = { workspace = true, features = ["write"] }
|
||||
@@ -1975,6 +1975,57 @@ fn metafile_dashed_pen_leaves_gaps() {
|
||||
assert!(ink.iter().filter(|b| !**b).count() > 30, "with gaps between them");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metafile_skewed_bitmap_is_drawn_with_its_transform() {
|
||||
use craft_metafile::write::{Image as MetafileImage, Op, emf};
|
||||
use kurbo::{Affine, Rect};
|
||||
|
||||
let image = std::sync::Arc::new(MetafileImage { width: 2, height: 2, rgba: [255, 0, 0, 255].repeat(4) });
|
||||
let xf = Affine::translate((25.0, 25.0)) * Affine::new([1.0, 0.25, 0.2, 1.0, 0.0, 0.0]) * Affine::scale(24.0);
|
||||
let bytes = emf(&[Op::Image { image, xf, opacity: 1.0 }], Rect::new(0.0, 0.0, 100.0, 100.0), "DeckCraft", "skewed bitmap").expect("EMF");
|
||||
let img = crate::metafile::rasterize(&bytes, 160).expect("raster");
|
||||
let red: Vec<_> = img.enumerate_pixels().filter(|(_, _, p)| p[0] > 180 && p[1] < 80 && p[3] > 128).collect();
|
||||
assert!(red.len() > 100, "the transformed image is visible: {} red pixels", red.len());
|
||||
let (min_x, max_x) = red.iter().fold((u32::MAX, 0), |(lo, hi), (x, _, _)| (lo.min(*x), hi.max(*x)));
|
||||
let (min_y, max_y) = red.iter().fold((u32::MAX, 0), |(lo, hi), (_, y, _)| (lo.min(*y), hi.max(*y)));
|
||||
assert!(max_x - min_x > 25 && max_y - min_y > 25, "the image keeps both transformed axes: x={min_x}..{max_x}, y={min_y}..{max_y}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metafile_clip_path_and_nondefault_pen_geometry_are_applied() {
|
||||
use craft_metafile::write::{Op, Pen, emf};
|
||||
use craft_metafile::{Cap, Join};
|
||||
use kurbo::{BezPath, Rect, Shape as _};
|
||||
|
||||
let mut triangle = BezPath::new();
|
||||
triangle.move_to((10.0, 10.0));
|
||||
triangle.line_to((90.0, 10.0));
|
||||
triangle.line_to((50.0, 90.0));
|
||||
triangle.close_path();
|
||||
|
||||
let mut bevel = BezPath::new();
|
||||
bevel.move_to((15.0, 35.0));
|
||||
bevel.line_to((50.0, 60.0));
|
||||
bevel.line_to((85.0, 35.0));
|
||||
let mut miter = BezPath::new();
|
||||
miter.move_to((15.0, 45.0));
|
||||
miter.line_to((50.0, 70.0));
|
||||
miter.line_to((85.0, 45.0));
|
||||
let pen = |join| Pen { rgb: [0, 0, 0], width: 5.0, cap: Cap::Square, join, miter: 4.0, dash: None };
|
||||
let ops = [
|
||||
Op::Clip { path: triangle, even_odd: false },
|
||||
Op::Fill { path: Rect::new(0.0, 0.0, 100.0, 100.0).to_path(0.1), even_odd: false, rgb: [255, 0, 0] },
|
||||
Op::Stroke { path: bevel, pen: pen(Join::Bevel) },
|
||||
Op::Stroke { path: miter, pen: pen(Join::Miter) },
|
||||
Op::Unclip,
|
||||
];
|
||||
let bytes = emf(&ops, Rect::new(0.0, 0.0, 100.0, 100.0), "DeckCraft", "clipped strokes").expect("EMF");
|
||||
let img = crate::metafile::rasterize(&bytes, 160).expect("raster");
|
||||
assert!(img.get_pixel(80, 12)[0] > 180, "inside the clip path is filled");
|
||||
assert_eq!(img.get_pixel(8, 80)[3], 0, "outside the clip path remains transparent");
|
||||
assert!(img.pixels().any(|p| p[3] > 128 && p[0] < 80), "square capped bevel and miter strokes are rendered");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metafile_text_ink_lands_at_its_reference_point() {
|
||||
// 2 × 1 inch (144 × 72 pt) drawn 288 px wide: 2 px per point. A 36-point "HH", top-left
|
||||
|
||||
Reference in new issue
Block a user