From 695f7c0d4bdd1c964c533d7e38cad9f22c7977aa Mon Sep 17 00:00:00 2001 From: bflatastic Date: Thu, 22 Oct 2026 00:18:00 +0700 Subject: [PATCH] =?UTF-8?q?G2:=20Effect=20=E2=80=BA=20Artistic=20=E2=80=BA?= =?UTF-8?q?=20Underpainting=20raster=20filter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed from #3035 onto main. --- crates/effects/src/lib.rs | 15 ++++ crates/effects/src/pixel/artistic.rs | 63 ++++++++++++++++- crates/effects/src/pixel/mod.rs | 21 +++++- crates/effects/src/pixel/tests.rs | 87 +++++++++++++++++++++++- crates/engine/src/tests_rasterfilters.rs | 3 +- crates/ui-egui/src/dialogs/effect.rs | 6 +- crates/ui-egui/src/i18n/bg.tsv | 3 + crates/ui-egui/src/i18n/cs.tsv | 3 + crates/ui-egui/src/i18n/da.tsv | 3 + crates/ui-egui/src/i18n/de.tsv | 3 + crates/ui-egui/src/i18n/el.tsv | 3 + crates/ui-egui/src/i18n/es.tsv | 3 + crates/ui-egui/src/i18n/fi.tsv | 3 + crates/ui-egui/src/i18n/fr.tsv | 3 + crates/ui-egui/src/i18n/hu.tsv | 3 + crates/ui-egui/src/i18n/id.tsv | 3 + crates/ui-egui/src/i18n/it.tsv | 3 + crates/ui-egui/src/i18n/ja.tsv | 3 + crates/ui-egui/src/i18n/ka.tsv | 3 + crates/ui-egui/src/i18n/ko.tsv | 3 + crates/ui-egui/src/i18n/nl.tsv | 3 + crates/ui-egui/src/i18n/pl.tsv | 3 + crates/ui-egui/src/i18n/pt-br.tsv | 3 + crates/ui-egui/src/i18n/ru.tsv | 3 + crates/ui-egui/src/i18n/sv.tsv | 3 + crates/ui-egui/src/i18n/uk.tsv | 3 + crates/ui-egui/src/i18n/vi.tsv | 3 + crates/ui-egui/src/i18n/zh-hans.tsv | 3 + crates/ui-egui/src/i18n/zh-hant.tsv | 3 + crates/ui-egui/src/tests_labels.rs | 1 + 30 files changed, 258 insertions(+), 7 deletions(-) diff --git a/crates/effects/src/lib.rs b/crates/effects/src/lib.rs index 4cb7ac55f..2094fba21 100644 --- a/crates/effects/src/lib.rs +++ b/crates/effects/src/lib.rs @@ -420,6 +420,21 @@ pub fn effect_catalog() -> Vec { "{brushSize: 0..10 (2; size of the sponge's pores), definition: 0..25 (12; how strongly lighter and darker blobs contrast), smoothness: 1..15 (5; softer blob edges)} paints the object as if dabbed with a sponge, in highly textured areas of contrasting colour. Coverage is kept. Original visual approximation; chosen VectorCraft defaults.", json!({"brushSize": 2.0, "definition": 12.0, "smoothness": 5.0}), ), + r( + "artistic.underpainting", + "Underpainting…", + ARTISTIC, + "{brushSize: 0..40 (6; wider, softer strokes), textureCoverage: 0..40 (16; more of the relief texture on the strokes), texture: \"brick\"|\"burlap\"|\"canvas\"|\"sandstone\" (\"canvas\"; surfaces made in code), scaling: % 50..200 (100), relief: 0..50 (4), lightDirection: \"bottom\"|\"bottomLeft\"|\"left\"|\"topLeft\"|\"top\"|\"topRight\"|\"right\"|\"bottomRight\" (\"top\"), invert: bool (false; turns the surface's heights over)} paints the object with broad strokes over a textured ground, keeping its coverage. Slider ranges follow the documented controls; numeric defaults are chosen for VectorCraft and are not verified against proprietary defaults. Original visual approximation.", + json!({ + "brushSize": 6.0, + "textureCoverage": 16.0, + "texture": "canvas", + "scaling": 100.0, + "relief": 4.0, + "lightDirection": "top", + "invert": false + }), + ), r( "artistic.watercolor", "Watercolor…", diff --git a/crates/effects/src/pixel/artistic.rs b/crates/effects/src/pixel/artistic.rs index 71381472f..b2484bd7c 100644 --- a/crates/effects/src/pixel/artistic.rs +++ b/crates/effects/src/pixel/artistic.rs @@ -1,5 +1,5 @@ //! Effect › Artistic (Cutout, Dry Brush, Film Grain, Neon Glow, Paint Daubs, Palette Knife, Plastic Wrap, Poster -//! Edges, Smudge Stick, Sponge and Watercolor). Original filters built from +//! Edges, Smudge Stick, Sponge, Underpainting and Watercolor). Original filters built from //! public behaviour documentation: //! and //! . @@ -10,7 +10,7 @@ use std::f64::consts::TAU; use super::brushstrokes::{Smear, mix, stroke_reach, unit, unpremultiply}; use super::edges::sobel; use super::pixelate::{Around, Place, Soft, cell, point_in, rand, value_noise}; -use super::texture::{luma, premultiply, straight}; +use super::texture::{self, Light, Texture, luma, premultiply, straight}; use super::{PixelSpace, blur_plane, pick}; use vectorcraft_geom::{Point, Vec2}; @@ -467,6 +467,65 @@ pub(super) fn glow_spread(size: f64) -> f64 { 0.25 * size.abs().min(24.0) } +/// Underpainting: broad brush strokes (`brush_size`, 0..40) over a relief `texture` surface +/// (`scaling`, `relief`, `light`, `invert`, as Texturizer uses), blended in as strongly as +/// `texture_coverage` (0..40) says. Coverage is kept. +#[allow(clippy::too_many_arguments)] +pub(super) fn underpainting( + px: &mut [[u8; 4]], + w: usize, + h: usize, + space: &PixelSpace, + brush_size: f64, + texture_coverage: f64, + texture: &Texture, + scaling: f64, + relief: f64, + light: Light, + invert: bool, +) { + if !(brush_size.is_finite() && texture_coverage.is_finite() && space.px.is_finite() && space.px > 0.0) { + return; + } + let brush_size = brush_size.clamp(0.0, 40.0); + let coverage = (texture_coverage / 40.0).clamp(0.0, 1.0) as f32; + let (mut colour, alpha) = planes(px); + let sigma = (0.1 * brush_size.max(0.25)) / space.px; + if sigma > 0.0 { + soften(&mut colour, &alpha, w, h, sigma); + } + for (k, p) in px.iter_mut().enumerate() { + if p[3] == 0 { + continue; + } + let c = [colour[0][k], colour[1][k], colour[2][k]]; + *p = premultiply(c, f32::from(p[3]) / 255.0); + } + if coverage <= 0.0 { + return; + } + let softened = px.to_vec(); + texture::texturizer(px, w, h, space, texture, scaling, relief, light, invert); + if coverage >= 1.0 { + return; + } + let mix = 1.0 - coverage; + for (k, p) in px.iter_mut().enumerate() { + if p[3] == 0 { + continue; + } + let a = f32::from(p[3]) / 255.0; + let tex = straight(*p); + let soft = straight(softened[k]); + let c = [ + (soft[0] * mix + tex[0] * coverage).clamp(0.0, 1.0), + (soft[1] * mix + tex[1] * coverage).clamp(0.0, 1.0), + (soft[2] * mix + tex[2] * coverage).clamp(0.0, 1.0), + ]; + *p = premultiply(c, a); + } +} + /// Neon Glow: the object in dimmed greys, lit by `colour` glowing from its light areas (`size` /// above 0) or from its dark areas (below 0), spread as far as |`size`| (0..24) says and as /// strong as `brightness` (0..50). Coverage is kept. diff --git a/crates/effects/src/pixel/mod.rs b/crates/effects/src/pixel/mod.rs index 669f9f405..6c465355f 100644 --- a/crates/effects/src/pixel/mod.rs +++ b/crates/effects/src/pixel/mod.rs @@ -44,7 +44,7 @@ pub use sketch::{HALFTONE_TYPES, HalftonePattern}; pub use texture::{GRAIN_TYPES, Grain, LIGHT_DIRECTIONS, Light, TEXTURES, TEXTURES_LOADED, Texture}; /// The Photoshop-style effect ids (all raster effects, see [`crate::is_raster`]). -pub const PIXEL_EFFECTS: [&str; 50] = [ +pub const PIXEL_EFFECTS: [&str; 51] = [ "artistic.cutout", "artistic.dryBrush", "artistic.filmGrain", @@ -55,6 +55,7 @@ pub const PIXEL_EFFECTS: [&str; 50] = [ "artistic.posterEdges", "artistic.smudgeStick", "artistic.sponge", + "artistic.underpainting", "artistic.watercolor", "blur.radial", "blur.smart", @@ -138,6 +139,10 @@ pub enum PixelFx { /// Artistic › Poster Edges: colours posterized to `posterization` + 2 levels (0..6) with black /// lines on the edges, as thick as `thickness` (0..10) and as dark as `intensity` (0..10). PosterEdges { thickness: f64, intensity: f64, posterization: f64 }, + /// Artistic › Underpainting: colours softened as widely as `brush_size` (0..40), then a + /// `texture` surface (`scaling`, `relief`, `light`, `invert`) blended in as strongly as + /// `texture_coverage` (0..40) says. + Underpainting { brush_size: f64, texture_coverage: f64, texture: Texture, scaling: f64, relief: f64, light: Light, invert: bool }, /// Blur › Radial Blur around the object's centre: along arcs (spin, an arc of `amount`°) or /// along rays (zoom, the content scaled by up to about ±`amount`/2 %), averaging 2^`passes` samples. RadialBlur { amount: f64, zoom: bool, passes: u32 }, @@ -332,6 +337,15 @@ pub(crate) fn parse(id: &str, p: &Value) -> Option { highlight: num(p, "highlightArea", 0.0).clamp(0.0, 20.0), intensity: num(p, "intensity", 10.0).clamp(0.0, 10.0), }, + "artistic.underpainting" => PixelFx::Underpainting { + brush_size: num(p, "brushSize", 6.0).clamp(0.0, 40.0), + texture_coverage: num(p, "textureCoverage", 16.0).clamp(0.0, 40.0), + texture: Texture::parse(text(p, "texture", "canvas")), + scaling: num(p, "scaling", 100.0).clamp(50.0, 200.0) / 100.0, + relief: num(p, "relief", 4.0).clamp(0.0, 50.0), + light: Light::parse(text(p, "lightDirection", "top")), + invert: flag(p, "invert", false), + }, "artistic.smudgeStick" => PixelFx::SmudgeStick { stroke: num(p, "strokeLength", 2.0).clamp(0.0, 10.0), highlight: num(p, "highlightArea", 12.0).clamp(0.0, 20.0), @@ -576,6 +590,7 @@ impl PixelFx { | PixelFx::NeonGlow { .. } | PixelFx::PlasticWrap { .. } | PixelFx::PosterEdges { .. } + | PixelFx::Underpainting { .. } | PixelFx::ColorHalftone { .. } | PixelFx::Mezzotint { .. } | PixelFx::Craquelure { .. } @@ -647,6 +662,7 @@ impl PixelFx { PixelFx::PlasticWrap { smoothness, .. } => Some(artistic::plastic_reach(smoothness)), // The edges' lines, spread round them. PixelFx::PosterEdges { thickness, .. } => Some(3.0 * (0.3 + 0.25 * thickness) + 1.0), + PixelFx::Underpainting { brush_size, .. } => Some(3.0 * (0.1 * brush_size.max(0.25)) + 1.0), // The dots' points, and the softened colour around them. PixelFx::Pointillize { cell } => Some(2.5 * cell), // The softened tones around the pixel. @@ -682,6 +698,9 @@ impl PixelFx { PixelFx::PosterEdges { thickness, intensity, posterization } => { artistic::poster_edges(px, w, h, space, thickness, intensity, posterization) } + PixelFx::Underpainting { brush_size, texture_coverage, ref texture, scaling, relief, light, invert } => { + artistic::underpainting(px, w, h, space, brush_size, texture_coverage, texture, scaling, relief, light, invert) + } PixelFx::RadialBlur { amount, zoom, passes } => blur::radial(px, w, h, space, amount, zoom, passes), PixelFx::SmartBlur { radius, threshold, samples, mode: SmartBlurMode::Normal } => { blur::smart(px, w, h, to_px(radius), threshold, samples) diff --git a/crates/effects/src/pixel/tests.rs b/crates/effects/src/pixel/tests.rs index 62f151ada..2f47a97a6 100644 --- a/crates/effects/src/pixel/tests.rs +++ b/crates/effects/src/pixel/tests.rs @@ -2441,12 +2441,38 @@ fn artistic_params_take_defaults_and_stay_in_range() { fx("artistic.neonGlow", json!({"glowSize": -1e308, "glowBrightness": 80, "color": "#ff0000"})), PixelFx::NeonGlow { size: -24.0, brightness: 50.0, colour: [1.0, 0.0, 0.0] } ); + let under = PixelFx::Underpainting { + brush_size: 6.0, + texture_coverage: 16.0, + texture: Texture::Canvas, + scaling: 1.0, + relief: 4.0, + light: Light::Top, + invert: false, + }; + assert_eq!(fx("artistic.underpainting", json!({})), under); + assert_eq!( + fx( + "artistic.underpainting", + json!({"brushSize": 99, "textureCoverage": -1, "texture": "brick", "scaling": 10, "relief": 60, "lightDirection": "bottomRight", "invert": true}) + ), + PixelFx::Underpainting { + brush_size: 40.0, + texture_coverage: 0.0, + texture: Texture::Brick, + scaling: 0.5, + relief: 50.0, + light: Light::BottomRight, + invert: true, + } + ); assert_eq!(fx("artistic.plasticWrap", json!({})), PixelFx::PlasticWrap { highlight: 20.0, detail: 12.0, smoothness: 15.0 }); assert_eq!( fx("artistic.plasticWrap", json!({"highlightStrength": -1, "detail": 99, "smoothness": 0})), PixelFx::PlasticWrap { highlight: 0.0, detail: 15.0, smoothness: 1.0 } ); - for id in ["artistic.cutout", "artistic.dryBrush", "artistic.neonGlow", "artistic.plasticWrap", "artistic.posterEdges"] { + for id in ["artistic.cutout", "artistic.dryBrush", "artistic.neonGlow", "artistic.plasticWrap", "artistic.posterEdges", "artistic.underpainting"] + { assert_eq!(fx(id, json!({})).outset(Rect::new(0.0, 0.0, 40.0, 30.0)), 0.0, "{id} keeps the object's shape"); } assert_eq!(fx("artistic.paintDaubs", json!({})), PixelFx::PaintDaubs { size: 10.0, sharpness: 25.0, kind: PaintDaubBrush::Simple }); @@ -2457,6 +2483,16 @@ fn artistic_params_take_defaults_and_stay_in_range() { let doc = crate::effect_info("artistic.paintDaubs").unwrap().params; assert!(PAINT_DAUB_BRUSH_TYPES.iter().all(|(_, v)| doc.contains(&format!("\"{v}\""))), "{doc}"); assert!(fx("artistic.paintDaubs", json!({})).outset(Rect::new(0.0, 0.0, 40.0, 30.0)) > 0.0); + for (id, key, table) in + [("artistic.underpainting", "texture", TEXTURES.as_slice()), ("artistic.underpainting", "lightDirection", LIGHT_DIRECTIONS.as_slice())] + { + let doc = crate::effect_info(id).unwrap().params; + let parsed: Vec = table.iter().map(|(_, v)| fx(id, json!({ key: v }))).collect(); + for (i, (_, v)) in table.iter().enumerate() { + assert!(doc.contains(&format!("\"{v}\"")), "{id} {v}"); + assert!(parsed.iter().skip(i + 1).all(|p| *p != parsed[i]), "{id} {v}"); + } + } } #[test] @@ -2475,6 +2511,15 @@ fn artistic_filters_leave_invalid_coordinate_spaces_alone() { PixelFx::NeonGlow { size: 5.0, brightness: 15.0, colour }, PixelFx::PlasticWrap { highlight: 20.0, detail: 12.0, smoothness: 15.0 }, PixelFx::PosterEdges { thickness: 2.0, intensity: 1.0, posterization: 2.0 }, + PixelFx::Underpainting { + brush_size: 6.0, + texture_coverage: 16.0, + texture: Texture::Canvas, + scaling: 1.0, + relief: 4.0, + light: Light::Top, + invert: false, + }, ]; for f in &filters { assert_ne!(run(f, &space(w, h)), src, "{f:?} changes the art in a valid space"); @@ -2496,6 +2541,24 @@ fn artistic_filters_leave_invalid_coordinate_spaces_alone() { PixelFx::PosterEdges { thickness: f64::NAN, intensity: 1.0, posterization: 2.0 }, PixelFx::PosterEdges { thickness: 2.0, intensity: f64::INFINITY, posterization: 2.0 }, PixelFx::PosterEdges { thickness: 2.0, intensity: 1.0, posterization: f64::NEG_INFINITY }, + PixelFx::Underpainting { + brush_size: f64::NAN, + texture_coverage: 16.0, + texture: Texture::Canvas, + scaling: 1.0, + relief: 4.0, + light: Light::Top, + invert: false, + }, + PixelFx::Underpainting { + brush_size: 6.0, + texture_coverage: f64::INFINITY, + texture: Texture::Canvas, + scaling: 1.0, + relief: 4.0, + light: Light::Top, + invert: false, + }, ] { if run(&f, &space(w, h)) != src { changed.push(format!("{f:?}")); @@ -2504,6 +2567,27 @@ fn artistic_filters_leave_invalid_coordinate_spaces_alone() { assert!(changed.is_empty(), "directly constructed non-finite parameters and invalid spaces are harmless: {changed:?}"); } +#[test] +fn underpainting_softens_more_with_a_larger_brush_and_keeps_coverage() { + let (w, h) = (48, 32); + let src = ramp(w, h); + let diff = |brush: f64| { + let mut out = src.clone(); + fx("artistic.underpainting", json!({"brushSize": brush, "textureCoverage": 0})).apply(&mut out, w, h, &space(w, h)); + out.as_chunks::<4>() + .0 + .iter() + .zip(src.as_chunks::<4>().0) + .filter(|(_, s)| s[3] == 255) + .map(|(o, s)| (0..3).map(|k| u32::from(o[k].abs_diff(s[k]))).sum::()) + .sum::() + }; + assert!(diff(40.0) > diff(2.0) * 2, "large brush {} vs small {}", diff(40.0), diff(2.0)); + let mut out = src.clone(); + fx("artistic.underpainting", json!({})).apply(&mut out, w, h, &space(w, h)); + assert!(out.as_chunks::<4>().0.iter().zip(src.as_chunks::<4>().0).all(|(o, s)| o[3] == s[3])); +} + #[test] fn plastic_wrap_adds_specular_highlights_and_keeps_coverage() { let (w, h) = (48, 32); @@ -2662,6 +2746,7 @@ fn artistic_filters_look_the_same_at_any_resolution() { ("artistic.cutout", json!({"edgeSimplicity": 6})), ("artistic.neonGlow", json!({"glowSize": 12, "glowBrightness": 30})), ("artistic.posterEdges", json!({"edgeThickness": 6, "edgeIntensity": 6})), + ("artistic.underpainting", json!({"brushSize": 12, "textureCoverage": 20, "relief": 10})), ] { let (mut a, mut b) = (coarse.clone(), fine.clone()); fx(id, p.clone()).apply(&mut a, w, h, &space(w, h)); diff --git a/crates/engine/src/tests_rasterfilters.rs b/crates/engine/src/tests_rasterfilters.rs index 52c4ab80c..af903bdc5 100644 --- a/crates/engine/src/tests_rasterfilters.rs +++ b/crates/engine/src/tests_rasterfilters.rs @@ -31,7 +31,7 @@ const BRUSH_STROKES: [(&str, &str); 8] = [ ]; /// Effect › Artistic, at their defaults. -const ARTISTIC: [(&str, &str); 11] = [ +const ARTISTIC: [(&str, &str); 12] = [ ("artistic.cutout", "{}"), ("artistic.dryBrush", "{}"), ("artistic.filmGrain", "{}"), @@ -41,6 +41,7 @@ const ARTISTIC: [(&str, &str); 11] = [ ("artistic.paletteKnife", "{}"), ("artistic.plasticWrap", "{}"), ("artistic.posterEdges", "{}"), + ("artistic.underpainting", "{}"), ("artistic.smudgeStick", "{}"), ("artistic.sponge", "{}"), ("artistic.watercolor", "{}"), diff --git a/crates/ui-egui/src/dialogs/effect.rs b/crates/ui-egui/src/dialogs/effect.rs index 94551f924..07bfba36a 100644 --- a/crates/ui-egui/src/dialogs/effect.rs +++ b/crates/ui-egui/src/dialogs/effect.rs @@ -301,8 +301,10 @@ fn choices(effect: &str, key: &str) -> Option { ("sketch.halftonePattern", "patternType") => Some(&vectorcraft_effects::pixel::HALFTONE_TYPES), ("sketch.plaster", "lightDirection") => Some(&vectorcraft_effects::pixel::LIGHT_DIRECTIONS), ("texture.grain", "grainType") => Some(&vectorcraft_effects::pixel::GRAIN_TYPES), - ("texture.texturizer", "texture") => Some(&vectorcraft_effects::pixel::TEXTURES), - ("sketch.basRelief" | "texture.texturizer", "lightDirection") => Some(&vectorcraft_effects::pixel::LIGHT_DIRECTIONS), + ("texture.texturizer" | "artistic.underpainting", "texture") => Some(&vectorcraft_effects::pixel::TEXTURES), + ("sketch.basRelief" | "texture.texturizer" | "artistic.underpainting", "lightDirection") => { + Some(&vectorcraft_effects::pixel::LIGHT_DIRECTIONS) + } ("video.deinterlace", "eliminate") => Some(&[("Odd Fields", "odd"), ("Even Fields", "even")]), ("video.deinterlace", "create") => Some(&[("Duplication", "duplication"), ("Interpolation", "interpolation")]), ("stylize.innerGlow", "source") => Some(&[("Center", "center"), ("Edge", "edge")]), diff --git a/crates/ui-egui/src/i18n/bg.tsv b/crates/ui-egui/src/i18n/bg.tsv index e76dbfd59..1e10132e6 100644 --- a/crates/ui-egui/src/i18n/bg.tsv +++ b/crates/ui-egui/src/i18n/bg.tsv @@ -4569,6 +4569,8 @@ lighting Light Светлина Palette Knife Нож за палитра Poster Edges… Плакатни ръбове… Poster Edges Плакатни ръбове + Underpainting… Подбоя… + Underpainting Подбоя Levels Нива Edge Simplicity Простота на ръбовете Edge Fidelity Точност на ръбовете @@ -5252,6 +5254,7 @@ theme Appearance Външен вид Watercolor… Акварел… Watercolor Акварел Brush Size Размер на четката + Texture Coverage Покритие на текстура Definition Дефиниция Brush Detail Детайл на четката Shadow Intensity Интензивност на сенките diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index d0657788e..c1c3e6bf2 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -5068,6 +5068,8 @@ imageTrace Outline Obrys Palette Knife Špachtle Poster Edges… Plakátové okraje… Poster Edges Plakátové okraje + Underpainting… Podmalba… + Underpainting Podmalba Levels Úrovně Edge Simplicity Jednoduchost okrajů Edge Fidelity Věrnost okrajů @@ -5283,6 +5285,7 @@ mark-style Japanese Japonské Watercolor… Akvarel… Watercolor Akvarel Brush Size Velikost štětce + Texture Coverage Krytí textury Definition Definice Brush Detail Detail štětce Shadow Intensity Intenzita stínů diff --git a/crates/ui-egui/src/i18n/da.tsv b/crates/ui-egui/src/i18n/da.tsv index 6dddf1ab9..5bdf1921e 100644 --- a/crates/ui-egui/src/i18n/da.tsv +++ b/crates/ui-egui/src/i18n/da.tsv @@ -5194,6 +5194,8 @@ swatch Bright Violet Kraftig violet Paint Daubs Malerklatter Palette Knife Paletkniv Poster Edges Plakatkanter + Underpainting… Undermaling… + Underpainting Undermaling Apply Data Set Anvend datasæt Cancel Pattern Editing Annullér redigering af mønster Copy Appearance Kopiér udseende @@ -5297,6 +5299,7 @@ swatch Bright Violet Kraftig violet Watercolor… Akvarel… Watercolor Akvarel Brush Size Penselstørrelse + Texture Coverage Teksturdækning Definition Definition Brush Detail Penseldetalje Shadow Intensity Skyggeintensitet diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index 0fc849939..51cbf7860 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -4655,6 +4655,8 @@ lighting Light Licht Palette Knife Palettenmesser Poster Edges… Posterkanten… Poster Edges Posterkanten + Underpainting… Untermalung… + Underpainting Untermalung Levels Stufen Edge Simplicity Kantenvereinfachung Edge Fidelity Kantentreue @@ -4862,6 +4864,7 @@ effect Soft Weich Watercolor… Aquarell… Watercolor Aquarell Brush Size Pinselgröße + Texture Coverage Texturabdeckung Definition Definition Brush Detail Pinseldetail Shadow Intensity Schattenintensität diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index f7138c421..0545b135b 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -2278,6 +2278,8 @@ lighting Light Φως Palette Knife Μαχαίρι παλέτας Poster Edges… Άκρες αφίσας… Poster Edges Άκρες αφίσας + Underpainting… Υποζωγραφία… + Underpainting Υποζωγραφία Levels Επίπεδα Edge Simplicity Απλότητα άκρων Edge Fidelity Πιστότητα άκρων @@ -5235,6 +5237,7 @@ effect Points Σημεία Watercolor… Υδατογραφία… Watercolor Υδατογραφία Brush Size Μέγεθος πινέλου + Texture Coverage Κάλυψη υφής Definition Ευκρίνεια Brush Detail Λεπτομέρεια πινέλου Shadow Intensity Ένταση σκιών diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 72e6b9e5c..69614c9d5 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -4656,6 +4656,8 @@ lighting Light Luz Palette Knife Espátula Poster Edges… Bordes de póster… Poster Edges Bordes de póster + Underpainting… Subpintura… + Underpainting Subpintura Levels Niveles Edge Simplicity Simplicidad de bordes Edge Fidelity Fidelidad de bordes @@ -5225,6 +5227,7 @@ mark-style Japanese Japonesas Watercolor… Acuarela… Watercolor Acuarela Brush Size Tamaño del pincel + Texture Coverage Cobertura de textura Definition Definición Brush Detail Detalle del pincel Shadow Intensity Intensidad de sombras diff --git a/crates/ui-egui/src/i18n/fi.tsv b/crates/ui-egui/src/i18n/fi.tsv index 9f652f8d6..6a3f34163 100644 --- a/crates/ui-egui/src/i18n/fi.tsv +++ b/crates/ui-egui/src/i18n/fi.tsv @@ -4963,6 +4963,8 @@ imageTrace Outline Ääriviiva Palette Knife Palettiveitsi Poster Edges… Julisteen reunat… Poster Edges Julisteen reunat + Underpainting… Alapinta… + Underpainting Alapinta Levels Tasot Edge Simplicity Reunojen yksinkertaisuus Edge Fidelity Reunojen tarkkuus @@ -5247,6 +5249,7 @@ mark-style Japanese Japanilainen Watercolor… Vesiväri… Watercolor Vesiväri Brush Size Siveltimen koko + Texture Coverage Tekstuurin peitto Definition Terävyys Brush Detail Siveltimen yksityiskohta Shadow Intensity Varjojen voimakkuus diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 59edc85f5..b3d49bade 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -4666,6 +4666,8 @@ lighting Light Lumière Palette Knife Couteau à palette Poster Edges… Bords d’affiche… Poster Edges Bords d’affiche + Underpainting… Sous-peinture… + Underpainting Sous-peinture Levels Niveaux Edge Simplicity Simplicité des contours Edge Fidelity Fidélité des contours @@ -5282,6 +5284,7 @@ theme Appearance Apparence Watercolor… Aquarelle… Watercolor Aquarelle Brush Size Taille du pinceau + Texture Coverage Couverture de texture Definition Définition Brush Detail Détail du pinceau Shadow Intensity Intensité des ombres diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index af87b9c08..e9e820d0e 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -1599,6 +1599,8 @@ file-filter Templates Sablonok Palette Knife Palettakés Poster Edges… Poszterszélek… Poster Edges Poszterszélek + Underpainting… Alapozás… + Underpainting Alapozás Levels Szintek Edge Simplicity Élek egyszerűsége Edge Fidelity Élek hűsége @@ -5269,6 +5271,7 @@ imageTrace Outline Körvonal Watercolor… Akvarell… Watercolor Akvarell Brush Size Ecsetméret + Texture Coverage Textúra fedettség Definition Kidolgozottság Brush Detail Ecsetrészletesség Shadow Intensity Árnyék intenzitása diff --git a/crates/ui-egui/src/i18n/id.tsv b/crates/ui-egui/src/i18n/id.tsv index fc71552c3..79f41ccf5 100644 --- a/crates/ui-egui/src/i18n/id.tsv +++ b/crates/ui-egui/src/i18n/id.tsv @@ -5194,6 +5194,8 @@ swatch Bright Violet Violet cerah Paint Daubs Coretan cat Palette Knife Pisau palet Poster Edges Tepi poster + Underpainting… Underpainting… + Underpainting Underpainting Apply Data Set Terapkan set data Cancel Pattern Editing Batalkan pengeditan pola Copy Appearance Salin tampilan @@ -5297,6 +5299,7 @@ swatch Bright Violet Violet cerah Watercolor… Cat air… Watercolor Cat air Brush Size Ukuran kuas + Texture Coverage Cakupan tekstur Definition Definisi Brush Detail Detail kuas Shadow Intensity Intensitas bayangan diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index c6ef8c1d4..5de6d61df 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -4698,6 +4698,8 @@ lighting Light Luce Palette Knife Spatola Poster Edges… Bordi poster… Poster Edges Bordi poster + Underpainting… Sottopittura… + Underpainting Sottopittura Levels Livelli Edge Simplicity Semplicità dei bordi Edge Fidelity Fedeltà dei bordi @@ -4897,6 +4899,7 @@ lighting Light Luce Watercolor… Acquerello… Watercolor Acquerello Brush Size Dimensione pennello + Texture Coverage Copertura texture Definition Definizione Brush Detail Dettaglio pennello Shadow Intensity Intensità ombre diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index 41d816197..6618e1e15 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -4737,6 +4737,8 @@ lighting Light ライト Palette Knife パレットナイフ Poster Edges… ポスターエッジ… Poster Edges ポスターエッジ + Underpainting… アンダーペインティング… + Underpainting アンダーペインティング Levels レベル数 Edge Simplicity エッジの単純さ Edge Fidelity エッジの正確さ @@ -4937,6 +4939,7 @@ lighting Light ライト Watercolor… 水彩… Watercolor 水彩 Brush Size ブラシサイズ + Texture Coverage テクスチャのかかり具合 Definition 精細度 Brush Detail ブラシの細かさ Shadow Intensity シャドウの強さ diff --git a/crates/ui-egui/src/i18n/ka.tsv b/crates/ui-egui/src/i18n/ka.tsv index aa907e018..7fa70cb04 100644 --- a/crates/ui-egui/src/i18n/ka.tsv +++ b/crates/ui-egui/src/i18n/ka.tsv @@ -5096,6 +5096,8 @@ imageTrace Outline კონტური Persistent მუდმივი Place from Library ბიბლიოთეკიდან განთავსება Poster Edges პოსტერის კიდეები + Underpainting… ქვეფენის მხატვრობა… + Underpainting ქვეფენის მხატვრობა Poster Edges… პოსტერის კიდეები… Posterization პოსტერიზაცია Previous Artboard წინა სამუშაო დაფა @@ -5228,6 +5230,7 @@ imageTrace Outline კონტური Watercolor… აკვარელი… Watercolor აკვარელი Brush Size ფუნჯის ზომა + Texture Coverage ტექსტურის დაფარვა Definition განსაზღვრულობა Brush Detail ფუნჯის დეტალი Shadow Intensity ჩრდილის ინტენსივობა diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index e4d7f8caa..199544432 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -4661,6 +4661,8 @@ lighting Light 광원 Palette Knife 팔레트 나이프 Poster Edges… 포스터 가장자리… Poster Edges 포스터 가장자리 + Underpainting… 언더페인팅… + Underpainting 언더페인팅 Levels 레벨 수 Edge Simplicity 가장자리 단순화 Edge Fidelity 가장자리 충실도 @@ -4860,6 +4862,7 @@ lighting Light 광원 Watercolor… 수채화… Watercolor 수채화 Brush Size 브러시 크기 + Texture Coverage 텍스처 적용 범위 Definition 선명도 Brush Detail 브러시 세부 묘사 Shadow Intensity 그림자 강도 diff --git a/crates/ui-egui/src/i18n/nl.tsv b/crates/ui-egui/src/i18n/nl.tsv index b76776350..df85856cf 100644 --- a/crates/ui-egui/src/i18n/nl.tsv +++ b/crates/ui-egui/src/i18n/nl.tsv @@ -5205,6 +5205,8 @@ swatch Bright Violet Felviolet Paint Daubs Verfstipjes Palette Knife Paletmes Poster Edges Posterranden + Underpainting… Onderlaag… + Underpainting Onderlaag Apply Data Set Gegevensset toepassen Cancel Pattern Editing Patroon bewerken annuleren Copy Appearance Uiterlijk kopiëren @@ -5339,6 +5341,7 @@ swatch Bright Violet Felviolet Watercolor… Aquarel… Watercolor Aquarel Brush Size Penseelgrootte + Texture Coverage Textuurdekking Definition Definitie Brush Detail Penseeldetail Shadow Intensity Schaduwintensiteit diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index eb272cfa4..8618138db 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -4901,6 +4901,8 @@ imageTrace Outline Kontur Palette Knife Szpachel Poster Edges… Krawędzie plakatu… Poster Edges Krawędzie plakatu + Underpainting… Podmalówka… + Underpainting Podmalówka Levels Poziomy Edge Simplicity Prostota krawędzi Edge Fidelity Wierność krawędzi @@ -5135,6 +5137,7 @@ mark-style Japanese Japońskie Watercolor… Akwarela… Watercolor Akwarela Brush Size Rozmiar pędzla + Texture Coverage Pokrycie teksturą Definition Wyrazistość Brush Detail Szczegółowość pędzla Shadow Intensity Intensywność cieni diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index f63074fc0..b89fa7608 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -4051,6 +4051,8 @@ axis Both Ambos Palette Knife Espátula Poster Edges… Bordas de pôster… Poster Edges Bordas de pôster + Underpainting… Subpintura… + Underpainting Subpintura Levels Níveis Edge Simplicity Simplicidade das bordas Edge Fidelity Fidelidade das bordas @@ -5200,6 +5202,7 @@ mark-style Japanese Japonesas Watercolor… Aquarela… Watercolor Aquarela Brush Size Tamanho do pincel + Texture Coverage Cobertura da textura Definition Definição Brush Detail Detalhe do pincel Shadow Intensity Intensidade da sombra diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 6a6bb6e9a..1d1939fcd 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -4694,6 +4694,8 @@ lighting Light Свет Palette Knife Нож для палитры Poster Edges… Края плаката… Poster Edges Края плаката + Underpainting… Подмалёвка… + Underpainting Подмалёвка Levels Уровни Edge Simplicity Простота краёв Edge Fidelity Точность краёв @@ -4893,6 +4895,7 @@ lighting Light Свет Watercolor… Акварель… Watercolor Акварель Brush Size Размер кисти + Texture Coverage Покрытие текстурой Definition Чёткость Brush Detail Детализация кисти Shadow Intensity Интенсивность теней diff --git a/crates/ui-egui/src/i18n/sv.tsv b/crates/ui-egui/src/i18n/sv.tsv index 82017cccf..4bbef3924 100644 --- a/crates/ui-egui/src/i18n/sv.tsv +++ b/crates/ui-egui/src/i18n/sv.tsv @@ -4575,6 +4575,8 @@ lighting Light Ljus Palette Knife Palettkniv Poster Edges… Affischkanter… Poster Edges Affischkanter + Underpainting… Undermålning… + Underpainting Undermålning Levels Nivåer Edge Simplicity Kantförenkling Edge Fidelity Kanttrohet @@ -5239,6 +5241,7 @@ theme Appearance Utseende Watercolor… Akvarell… Watercolor Akvarell Brush Size Penselstorlek + Texture Coverage Texturtäckning Definition Skärpa Brush Detail Penseldetalj Shadow Intensity Skuggintensitet diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index 599eb3d5f..b950aca2a 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -4678,6 +4678,8 @@ lighting Light Світло Palette Knife Ніж палітри Poster Edges… Плакатні краї… Poster Edges Плакатні краї + Underpainting… Підмалювання… + Underpainting Підмалювання Levels Рівні Edge Simplicity Простота країв Edge Fidelity Точність країв @@ -4877,6 +4879,7 @@ lighting Light Світло Watercolor… Акварель… Watercolor Акварель Brush Size Розмір пензля + Texture Coverage Покриття текстурою Definition Чіткість Brush Detail Деталізація пензля Shadow Intensity Інтенсивність тіней diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 89beb2e17..54e8d3c65 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -1280,6 +1280,8 @@ Palette Knife Dao palette Poster Edges… Viền áp phích… Poster Edges Viền áp phích + Underpainting… Lớp sơn nền… + Underpainting Lớp sơn nền Levels Số mức Edge Simplicity Độ đơn giản của cạnh Edge Fidelity Độ trung thực của cạnh @@ -4877,6 +4879,7 @@ theme Appearance Giao diện Watercolor… Màu nước… Watercolor Màu nước Brush Size Kích thước cọ + Texture Coverage Độ phủ kết cấu Definition Độ nét Brush Detail Chi tiết cọ Shadow Intensity Cường độ bóng diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 1470c85f2..851c5b727 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -4962,6 +4962,8 @@ lighting Light 光源 Palette Knife 调色刀 Poster Edges… 海报边缘… Poster Edges 海报边缘 + Underpainting… 底纹效果… + Underpainting 底纹效果 Levels 色阶数 Edge Simplicity 边缘简化度 Edge Fidelity 边缘逼真度 @@ -5118,6 +5120,7 @@ lighting Light 光源 Watercolor… 水彩… Watercolor 水彩 Brush Size 画笔大小 + Texture Coverage 纹理覆盖 Definition 清晰度 Brush Detail 画笔细节 Shadow Intensity 阴影强度 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index c6acb7995..fde67267e 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -4768,6 +4768,8 @@ lighting Light 光源 Palette Knife 調色刀 Poster Edges… 海報邊緣… Poster Edges 海報邊緣 + Underpainting… 底紋效果… + Underpainting 底紋效果 Levels 色階數 Edge Simplicity 邊緣簡化度 Edge Fidelity 邊緣逼真度 @@ -4928,6 +4930,7 @@ lighting Light 光源 Watercolor… 水彩… Watercolor 水彩 Brush Size 筆刷大小 + Texture Coverage 紋理覆蓋 Definition 清晰度 Brush Detail 筆刷細節 Shadow Intensity 陰影強度 diff --git a/crates/ui-egui/src/tests_labels.rs b/crates/ui-egui/src/tests_labels.rs index 02828e49b..67dfe48a3 100644 --- a/crates/ui-egui/src/tests_labels.rs +++ b/crates/ui-egui/src/tests_labels.rs @@ -99,6 +99,7 @@ fn effect_menu_lists_the_artistic_filters_before_blur() { "Poster Edges…", "Smudge Stick…", "Sponge…", + "Underpainting…", "Watercolor…" ] );