Merge main into feat/character-anti-aliasing-method

# Conflicts:
#	crates/engine/src/cmd/panelcmds.rs
#	crates/ui-egui/src/panels/character.rs
This commit is contained in:
dotCooCoo
2026-10-31 18:10:03 -07:00
473 changed files with 28565 additions and 3561 deletions
+20 -10
View File
@@ -4,7 +4,7 @@
//! ([`PatternDef::period`]) is rasterized at the device scale it is painted at, rounded up to a
//! power of two and capped ([`raster_scale`]), and used as an image paint with `Extend::Repeat`,
//! with the paint transform mapping pixels → pattern space → document. Tiles are cached per
//! pattern name and raster scale (and ink plane, see [`crate::ink`]) within
//! pattern name, raster scale, undecoded-image mark setting and ink plane (see [`crate::ink`]) within
//! [`lru::PATTERN_BUDGET`]. A tile is used while the pattern's definition is the one it was
//! rasterized from (art `Arc` identity, tile, tile type, overlap): the pattern's "revision", and,
//! when its art shows more than itself (a symbol, another pattern, an image, type, a brush), while
@@ -33,9 +33,9 @@ use crate::{Frame, RenderOptions, Rendered, Renderer};
/// Largest super-tile raster side (pixels).
const MAX_TILE_PX: f64 = 2048.0;
/// What a tile is kept under: the pattern's name and the bits of its raster scale
/// ([`raster_scale`]).
type TileKey = (String, u64, Ink);
/// What a tile is kept under: the pattern's name, the bits of its raster scale
/// ([`raster_scale`]), ink plane and undecoded-image mark setting.
type TileKey = (String, u64, Ink, bool);
/// What a tile was drawn from besides its pattern's own art, for art that shows more than itself:
/// the art of every pattern and symbol and the pixels of every image in the document, the
@@ -169,12 +169,20 @@ pub(crate) fn raster_scale(s: f64, period: (f64, f64)) -> f64 {
/// Rasterize `region` (pattern space) of the infinite tiling into a `w`×`h` pixmap, colours as
/// `ink` paints them.
fn rasterize(r: &mut Renderer, doc: &Document, def: &PatternDef, region: Rect, w: u16, h: u16, ink: Ink) -> (Pixmap, bool) {
let (w, h) = (w.max(1), h.max(1));
fn rasterize(
r: &mut Renderer,
doc: &Document,
def: &PatternDef,
region: Rect,
size: (u16, u16),
ink: Ink,
mark_undecoded_images: bool,
) -> (Pixmap, bool) {
let (w, h) = (size.0.max(1), size.1.max(1));
let mut ctx = crate::single_threaded_context(w, h);
let view = Affine::scale_non_uniform(w as f64 / region.width().max(1e-9), h as f64 / region.height().max(1e-9))
* Affine::translate(-region.origin().to_vec2());
let opts = RenderOptions::default();
let opts = RenderOptions { mark_undecoded_images, ..Default::default() };
r.image_left_out = Some(false);
let pattern_images_left_out = images_left_out();
r.check_plugins();
@@ -255,7 +263,7 @@ pub(crate) fn set_pattern_paint(ctx: &mut RenderContext, name: &str, xf: Affine,
let (pw, ph) = def.period();
let scale = raster_scale(s, (pw, ph));
let params = (def.tile, def.tile_type, def.overlap);
let key = (name.to_string(), scale.to_bits(), ink);
let key = (name.to_string(), scale.to_bits(), ink, f.opts.mark_undecoded_images);
let cms = vectorcraft_color::cms::active();
let hit = CACHE.with(|c| {
let mut c = c.borrow_mut();
@@ -284,7 +292,9 @@ pub(crate) fn set_pattern_paint(ctx: &mut RenderContext, name: &str, xf: Affine,
let w = (pw * scale).ceil().clamp(1.0, 4096.0) as u16;
let h = (ph * scale).ceil().clamp(1.0, 4096.0) as u16;
let before = crate::paint::decode_failures();
let Some((pm, image_left_out)) = with_tile_renderer(|r| rasterize(r, doc, def, Rect::new(0.0, 0.0, pw, ph), w, h, ink)) else {
let Some((pm, image_left_out)) =
with_tile_renderer(|r| rasterize(r, doc, def, Rect::new(0.0, 0.0, pw, ph), (w, h), ink, f.opts.mark_undecoded_images))
else {
ctx.set_paint(missing());
return true;
};
@@ -323,7 +333,7 @@ pub fn render_pattern_swatch(doc: &Document, name: &str, size: u32) -> Option<Re
let side = w.max(h);
let region = Rect::from_center_size((w / 2.0, h / 2.0), (side, side));
let px = size.clamp(1, 1024) as u16;
let (pm, _) = with_tile_renderer(|r| rasterize(r, doc, def, region, px, px, Ink::Display))?;
let (pm, _) = with_tile_renderer(|r| rasterize(r, doc, def, region, (px, px), Ink::Display, false))?;
Some(Rendered { width: px as u32, height: px as u32, pixels: pm.data_as_u8_slice().to_vec() })
}