mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
G2: Effect › Artistic › Fresco raster filter
Squashed from #3096 onto main.
This commit is contained in:
@@ -379,6 +379,13 @@ pub fn effect_catalog() -> Vec<EffectInfo> {
|
||||
"{grain: 0..20 (4; monochrome noise in shadows and midtones), highlightArea: 0..20 (0; widens the bright highlight area), intensity: 0..10 (10; highlight strength and quieter highlight grain)}. Smooth document-space grain follows translations; minification uses approximate footprint filtering. Coverage and pure white are preserved; black takes light speckles, and saturated colour channels may clip. Grain 0 with either highlightArea 0 or intensity 0 leaves the art unchanged. Original visual approximation; chosen VectorCraft defaults.",
|
||||
json!({"grain": 4.0, "highlightArea": 0.0, "intensity": 10.0}),
|
||||
),
|
||||
r(
|
||||
"artistic.fresco",
|
||||
"Fresco…",
|
||||
ARTISTIC,
|
||||
"{brushSize: 1..10 (2; wider brush dabs), brushDetail: 0..10 (10; sharper edges and less smoothing), texture: 1..3 (1; deeper plaster relief)} repaints the object as coarse pigment on a textured wall, keeping its coverage. Original visual approximation; chosen VectorCraft defaults.",
|
||||
json!({"brushSize": 2.0, "brushDetail": 10.0, "texture": 1.0}),
|
||||
),
|
||||
r(
|
||||
"artistic.neonGlow",
|
||||
"Neon Glow…",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Effect › Artistic (Colored Pencil, Cutout, Dry Brush, Film Grain, Neon Glow, Paint Daubs, Palette Knife, Plastic Wrap, Poster
|
||||
//! Effect › Artistic (Colored Pencil, Cutout, Dry Brush, Film Grain, Fresco, Neon Glow, Paint Daubs, Palette Knife, Plastic Wrap, Poster
|
||||
//! Edges, Rough Pastels, Smudge Stick, Sponge, Underpainting and Watercolor). Original filters built from
|
||||
//! public behaviour documentation:
|
||||
//! <https://helpx.adobe.com/illustrator/using/summary-effects.html> and
|
||||
@@ -10,7 +10,7 @@ use std::f64::consts::TAU;
|
||||
use super::brushstrokes::{LEFT, RIGHT, Smear, TONE_SOFTNESS, mix, streak, stroke_reach, unit, unpremultiply};
|
||||
use super::edges::sobel;
|
||||
use super::pixelate::{Around, Place, Soft, cell, point_in, rand, value_noise};
|
||||
use super::texture::{self, Light, Texture, Tones, luma, premultiply, straight, texturizer};
|
||||
use super::texture::{self, Light, Texture, Tones, luma, premultiply, smooth_noise, straight, texturizer};
|
||||
use super::{PixelSpace, blur_plane, pick};
|
||||
use vectorcraft_geom::{Point, Vec2};
|
||||
|
||||
@@ -72,6 +72,7 @@ pub(super) fn paint_daub_radius(size: f64) -> f64 {
|
||||
size.clamp(1.0, 50.0) * 0.48
|
||||
}
|
||||
const SALT_PENCIL: u64 = 304;
|
||||
const SALT_FRESCO: u64 = 320;
|
||||
|
||||
/// Keep the last cell's four corner values: magnified adjacent pixels often share a cell.
|
||||
/// The cache changes only cost, never the field, and needs constant storage per raster.
|
||||
@@ -426,6 +427,59 @@ fn rough_bristle(p: Point, k: u64) -> f32 {
|
||||
rand(SALT_DAUB + 3, i, j, k) as f32
|
||||
}
|
||||
|
||||
/// Fresco: coarse brush dabs on a plaster wall. `brush_size` (1..10) sets dab spacing,
|
||||
/// `brush_detail` (0..10) keeps sharper edges when high, and `texture` (1..3) deepens the
|
||||
/// relief. Coverage is kept.
|
||||
pub(super) fn fresco(px: &mut [[u8; 4]], w: usize, h: usize, space: &PixelSpace, brush_size: f64, brush_detail: f64, texture: f64) {
|
||||
if !([brush_size, brush_detail, texture].iter().all(|v| v.is_finite()) && space.px.is_finite() && space.px > 0.0) {
|
||||
return;
|
||||
}
|
||||
let Some(place) = Place::new(space, w, h) else { return };
|
||||
let brush_size = brush_size.clamp(1.0, 10.0);
|
||||
let brush_detail = brush_detail.clamp(0.0, 10.0);
|
||||
let texture = texture.round().clamp(1.0, 3.0);
|
||||
let side = 2.0 + 1.8 * brush_size;
|
||||
let sigma = (0.15 * (10.0 - brush_detail) * brush_size / place.px).max(0.0);
|
||||
let soft = Soft::new(px, w, sigma);
|
||||
let tex_strength = 0.08 + 0.07 * (texture - 1.0);
|
||||
let tex_scale = 3.0 / texture;
|
||||
let streak_mix = 0.25 * (1.0 - brush_detail / 10.0);
|
||||
place.each(px, |x, y, p| {
|
||||
if p[3] == 0 {
|
||||
return;
|
||||
}
|
||||
let q = place.at(x, y);
|
||||
let (Some(i), Some(j)) = (cell(q.x / side), cell(q.y / side)) else { return };
|
||||
let jx = (rand(SALT_FRESCO, i, j, 0) - 0.5) * 0.35 * side;
|
||||
let jy = (rand(SALT_FRESCO, i, j, 1) - 0.5) * 0.35 * side;
|
||||
let sample = Point::new(q.x + jx, q.y + jy);
|
||||
let mut sampled = soft.at(place.index(sample));
|
||||
if sampled[3] <= 0.0 {
|
||||
sampled = soft.at(place.index(q));
|
||||
}
|
||||
if sampled[3] <= 0.0 {
|
||||
return;
|
||||
}
|
||||
let [r, g, b, alpha] = sampled;
|
||||
let c = [r, g, b].map(|v| v / alpha);
|
||||
let angle = TAU * rand(SALT_FRESCO, i, j, 2);
|
||||
let (fx, fy) = (q.x - i as f64 * side, q.y - j as f64 * side);
|
||||
let along = fx * angle.cos() + fy * angle.sin();
|
||||
let streak = (1.0 - streak_mix * (0.5 + 0.5 * (along / side).sin().powi(2))) as f32;
|
||||
let bump = (1.0 + tex_strength * smooth_noise(SALT_FRESCO + 3, q, tex_scale * side)) as f32;
|
||||
let lit = c.map(|v| (v * streak * bump).clamp(0.0, 1.0));
|
||||
*p = premultiply(lit, f32::from(p[3]) / 255.0);
|
||||
});
|
||||
}
|
||||
|
||||
/// How far (document units) a Fresco dab can reach from a pixel.
|
||||
pub(super) fn fresco_reach(brush_size: f64, brush_detail: f64) -> f64 {
|
||||
let brush_size = brush_size.clamp(1.0, 10.0);
|
||||
let brush_detail = brush_detail.clamp(0.0, 10.0);
|
||||
let side = 2.0 + 1.8 * brush_size;
|
||||
side + 0.15 * (10.0 - brush_detail) * brush_size
|
||||
}
|
||||
|
||||
/// How far (document units) Plastic Wrap's softened relief is sampled at `smoothness` (1..15).
|
||||
pub(super) fn plastic_reach(smoothness: f64) -> f64 {
|
||||
3.0 * (0.15 + 0.35 * smoothness.clamp(1.0, 15.0))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Photoshop-style raster effects (Effect › Artistic › Colored Pencil, Cutout, Dry Brush, Film Grain, Neon Glow, Paint Daubs, Plastic Wrap and
|
||||
//! Photoshop-style raster effects (Effect › Artistic › Colored Pencil, Cutout, Dry Brush, Film Grain, Fresco, Neon Glow, Paint Daubs, Plastic Wrap and
|
||||
//! Poster Edges, Rough Pastels, Smudge Stick, Sponge and Watercolor, Blur › Radial Blur and Smart Blur, Brush Strokes › Accented Edges, Angled Strokes,
|
||||
//! Crosshatch, Dark Strokes, Ink Outlines, Spatter, Sprayed Strokes and Sumi-e, Distort › Diffuse
|
||||
//! Glow, Glass and Ocean Ripple, Pixelate › Color Halftone, Crystallize, Mezzotint and Pointillize,
|
||||
@@ -44,11 +44,12 @@ 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; 54] = [
|
||||
pub const PIXEL_EFFECTS: [&str; 55] = [
|
||||
"artistic.coloredPencil",
|
||||
"artistic.cutout",
|
||||
"artistic.dryBrush",
|
||||
"artistic.filmGrain",
|
||||
"artistic.fresco",
|
||||
"artistic.neonGlow",
|
||||
"artistic.paintDaubs",
|
||||
"artistic.paletteKnife",
|
||||
@@ -118,6 +119,9 @@ pub enum PixelFx {
|
||||
/// Artistic › Film Grain: monochrome grain in shadows and midtones, a wider bright
|
||||
/// highlight area (0..20), and tonal intensity (0..10), preserving coverage.
|
||||
FilmGrain { grain: f64, highlight: f64, intensity: f64 },
|
||||
/// Artistic › Fresco: coarse brush dabs on plaster; `brush_size` (1..10), `brush_detail`
|
||||
/// (0..10) and `texture` (1..3).
|
||||
Fresco { brush_size: f64, brush_detail: f64, texture: f64 },
|
||||
/// Artistic › Smudge Stick: the dark areas smudged along short diagonal strokes `stroke`
|
||||
/// (0..10) long, the light areas (widened by `highlight`, 0..20) smudged longer and lightened
|
||||
/// by up to `intensity` (0..10).
|
||||
@@ -374,6 +378,11 @@ pub(crate) fn parse(id: &str, p: &Value) -> Option<PixelFx> {
|
||||
light: Light::parse(text(p, "lightDirection", "top")),
|
||||
invert: flag(p, "invert", false),
|
||||
},
|
||||
"artistic.fresco" => PixelFx::Fresco {
|
||||
brush_size: num(p, "brushSize", 2.0).clamp(1.0, 10.0),
|
||||
brush_detail: num(p, "brushDetail", 10.0).clamp(0.0, 10.0),
|
||||
texture: num(p, "texture", 1.0).round().clamp(1.0, 3.0),
|
||||
},
|
||||
"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),
|
||||
@@ -621,6 +630,7 @@ impl PixelFx {
|
||||
PixelFx::SmudgeStick { .. } | PixelFx::Sponge { .. } | PixelFx::Watercolor { .. } => 0.0,
|
||||
PixelFx::FilmGrain { .. }
|
||||
| PixelFx::ColoredPencil { .. }
|
||||
| PixelFx::Fresco { .. }
|
||||
| PixelFx::Cutout { .. }
|
||||
| PixelFx::DryBrush { .. }
|
||||
| PixelFx::NeonGlow { .. }
|
||||
@@ -687,6 +697,7 @@ impl PixelFx {
|
||||
| PixelFx::HalftonePattern { .. }
|
||||
| PixelFx::NotePaper { .. }
|
||||
| PixelFx::Reticulation { .. } => Some(0.0),
|
||||
PixelFx::Fresco { brush_size, brush_detail, .. } => Some(artistic::fresco_reach(brush_size, brush_detail)),
|
||||
PixelFx::DryBrush { size, detail, .. } => Some(artistic::dry_brush_reach(size, detail)),
|
||||
PixelFx::Plaster { smoothness, .. } => Some(sketch::plaster_reach(smoothness)),
|
||||
PixelFx::PaintDaubs { size, .. } => Some(artistic::paint_daub_radius(size) + size * 0.15),
|
||||
@@ -725,6 +736,7 @@ impl PixelFx {
|
||||
PixelFx::Cutout { levels, simplicity, fidelity } => artistic::cutout(px, w, h, space, levels, simplicity, fidelity),
|
||||
PixelFx::DryBrush { size, detail, texture } => artistic::dry_brush(px, w, h, space, size, detail, texture),
|
||||
PixelFx::FilmGrain { grain, highlight, intensity } => artistic::film_grain(px, w, h, space, grain, highlight, intensity),
|
||||
PixelFx::Fresco { brush_size, brush_detail, texture } => artistic::fresco(px, w, h, space, brush_size, brush_detail, texture),
|
||||
PixelFx::SmudgeStick { stroke, highlight, intensity } => paint::smudge_stick(px, w, h, space, stroke, highlight, intensity),
|
||||
PixelFx::Sponge { brush, definition, smoothness } => paint::sponge(px, w, h, space, brush, definition, smoothness),
|
||||
PixelFx::Watercolor { detail, shadow, texture } => paint::watercolor(px, w, h, space, detail, shadow, texture),
|
||||
|
||||
@@ -2549,6 +2549,11 @@ fn artistic_params_take_defaults_and_stay_in_range() {
|
||||
),
|
||||
PixelFx::RoughPastels { length: 0.0, detail: 20.0, texture: Texture::Canvas, scaling: 0.5, relief: 50.0, light: Light::Top, invert: true }
|
||||
);
|
||||
assert_eq!(fx("artistic.fresco", json!({})), PixelFx::Fresco { brush_size: 2.0, brush_detail: 10.0, texture: 1.0 });
|
||||
assert_eq!(
|
||||
fx("artistic.fresco", json!({"brushSize": 0, "brushDetail": 99, "texture": 4.7})),
|
||||
PixelFx::Fresco { brush_size: 1.0, brush_detail: 10.0, texture: 3.0 }
|
||||
);
|
||||
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})),
|
||||
@@ -2558,6 +2563,7 @@ fn artistic_params_take_defaults_and_stay_in_range() {
|
||||
"artistic.coloredPencil",
|
||||
"artistic.cutout",
|
||||
"artistic.dryBrush",
|
||||
"artistic.fresco",
|
||||
"artistic.neonGlow",
|
||||
"artistic.plasticWrap",
|
||||
"artistic.posterEdges",
|
||||
@@ -2612,6 +2618,7 @@ fn artistic_filters_leave_invalid_coordinate_spaces_alone() {
|
||||
let filters = [
|
||||
PixelFx::Cutout { levels: 4.0, simplicity: 4.0, fidelity: 2.0 },
|
||||
PixelFx::DryBrush { size: 2.0, detail: 10.0, texture: 1.0 },
|
||||
PixelFx::Fresco { brush_size: 2.0, brush_detail: 10.0, texture: 1.0 },
|
||||
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 },
|
||||
@@ -2664,6 +2671,9 @@ fn artistic_filters_leave_invalid_coordinate_spaces_alone() {
|
||||
light: Light::Top,
|
||||
invert: false,
|
||||
},
|
||||
PixelFx::Fresco { brush_size: f64::NAN, brush_detail: 10.0, texture: 1.0 },
|
||||
PixelFx::Fresco { brush_size: 2.0, brush_detail: f64::INFINITY, texture: 1.0 },
|
||||
PixelFx::Fresco { brush_size: 2.0, brush_detail: 10.0, texture: f64::NEG_INFINITY },
|
||||
] {
|
||||
if run(&f, &space(w, h)) != src {
|
||||
changed.push(format!("{f:?}"));
|
||||
@@ -2693,6 +2703,22 @@ fn underpainting_softens_more_with_a_larger_brush_and_keeps_coverage() {
|
||||
assert!(out.as_chunks::<4>().0.iter().zip(src.as_chunks::<4>().0).all(|(o, s)| o[3] == s[3]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fresco_keeps_coverage_and_responds_to_texture() {
|
||||
let (w, h) = (48, 32);
|
||||
let src = ramp(w, h);
|
||||
let mut low = src.clone();
|
||||
let mut high = src.clone();
|
||||
fx("artistic.fresco", json!({"texture": 1})).apply(&mut low, w, h, &space(w, h));
|
||||
fx("artistic.fresco", json!({"texture": 3})).apply(&mut high, w, h, &space(w, h));
|
||||
assert_ne!(low, src);
|
||||
assert_ne!(high, src);
|
||||
assert_ne!(low, high, "deeper texture changes the relief");
|
||||
for (a, b) in low.as_chunks::<4>().0.iter().zip(src.as_chunks::<4>().0) {
|
||||
assert_eq!(a[3], b[3], "alpha is preserved");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plastic_wrap_adds_specular_highlights_and_keeps_coverage() {
|
||||
let (w, h) = (48, 32);
|
||||
|
||||
@@ -31,11 +31,12 @@ const BRUSH_STROKES: [(&str, &str); 8] = [
|
||||
];
|
||||
|
||||
/// Effect › Artistic, at their defaults.
|
||||
const ARTISTIC: [(&str, &str); 14] = [
|
||||
const ARTISTIC: [(&str, &str); 15] = [
|
||||
("artistic.coloredPencil", "{}"),
|
||||
("artistic.cutout", "{}"),
|
||||
("artistic.dryBrush", "{}"),
|
||||
("artistic.filmGrain", "{}"),
|
||||
("artistic.fresco", "{}"),
|
||||
("artistic.neonGlow", "{}"),
|
||||
// Wide Blurry softens dabs; Simple leaves uniform fills unchanged on the striped art.
|
||||
("artistic.paintDaubs", r#"{"brushType": "wideBlurry"}"#),
|
||||
@@ -214,6 +215,7 @@ fn artistic_settings_survive_a_save_and_open() {
|
||||
json!({"levels": 3.0, "edgeSimplicity": 2.0, "edgeFidelity": 3.0}),
|
||||
[json!({"levels": 2.0}), json!({"edgeSimplicity": 10.0})],
|
||||
),
|
||||
("artistic.fresco", json!({"brushSize": 4.0, "brushDetail": 6.0, "texture": 2.0}), [json!({"brushSize": 8.0}), json!({"texture": 3.0})]),
|
||||
(
|
||||
"artistic.neonGlow",
|
||||
json!({"glowSize": -6.0, "glowBrightness": 30.0, "color": "#ff3300"}),
|
||||
|
||||
@@ -5326,3 +5326,5 @@ theme Appearance Външен вид
|
||||
Water Paper Мокра хартия
|
||||
Ruby… Руби…
|
||||
Ruby Руби
|
||||
Fresco… Фреска…
|
||||
Fresco Фреска
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5369,3 +5369,5 @@ mark-style Japanese Japonské
|
||||
Water Paper Mokrý papír
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Freska…
|
||||
Fresco Freska
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5342,3 +5342,5 @@ swatch Bright Violet Kraftig violet
|
||||
Water Paper Vådt papir
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresko…
|
||||
Fresco Fresko
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4950,3 +4950,5 @@ effect Soft Weich
|
||||
Water Paper Feuchtes Papier
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresko…
|
||||
Fresco Fresko
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5321,3 +5321,5 @@ effect Points Σημεία
|
||||
Water Paper Βρεγμένο χαρτί
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Νωπογραφία…
|
||||
Fresco Νωπογραφία
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2039 and column 19.
|
@@ -5311,3 +5311,5 @@ mark-style Japanese Japonesas
|
||||
Water Paper Papel mojado
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresco…
|
||||
Fresco Fresco
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5400,3 +5400,5 @@ swatch Bright Violet Kirkas violetti
|
||||
Water Paper Märkä paperi
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresko…
|
||||
Fresco Fresko
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5368,3 +5368,5 @@ theme Appearance Apparence
|
||||
Water Paper Papier humide
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresque…
|
||||
Fresco Fresque
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5355,3 +5355,5 @@ imageTrace Outline Körvonal
|
||||
Water Paper Nedves papír
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Freskó…
|
||||
Fresco Freskó
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5342,3 +5342,5 @@ swatch Bright Violet Violet cerah
|
||||
Water Paper Kertas Basah
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresko…
|
||||
Fresco Fresko
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 3809 and column 19.
|
@@ -4984,3 +4984,5 @@ lighting Light Luce
|
||||
Water Paper Carta bagnata
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Affresco…
|
||||
Fresco Affresco
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5031,3 +5031,5 @@ lighting Light ライト
|
||||
Yonroku-ban 四六判
|
||||
Ruby… ルビ…
|
||||
Ruby ルビ
|
||||
Fresco… フレスコ…
|
||||
Fresco フレスコ
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5279,3 +5279,5 @@ imageTrace Outline კონტური
|
||||
selects several, or draws one inside an artboard) რამდენიმეს მონიშნავს ან ახალს სამუშაო დაფის შიგნით ხატავს)
|
||||
Ruby… რუბი…
|
||||
Ruby რუბი
|
||||
Fresco… ფრესკა…
|
||||
Fresco ფრესკა
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4947,3 +4947,5 @@ lighting Light 광원
|
||||
Water Paper 물 종이
|
||||
Ruby… 루비…
|
||||
Ruby 루비
|
||||
Fresco… 프레스코…
|
||||
Fresco 프레스코
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5384,3 +5384,5 @@ swatch Bright Violet Felviolet
|
||||
Water Paper Nat papier
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresco…
|
||||
Fresco Fresco
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5221,3 +5221,5 @@ mark-style Japanese Japońskie
|
||||
Water Paper Mokry papier
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresk…
|
||||
Fresco Fresk
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5286,3 +5286,5 @@ mark-style Japanese Japonesas
|
||||
Water Paper Papel molhado
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Afresco…
|
||||
Fresco Afresco
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4980,3 +4980,5 @@ lighting Light Свет
|
||||
Water Paper Мокрая бумага
|
||||
Ruby… Руби…
|
||||
Ruby Руби
|
||||
Fresco… Фреска…
|
||||
Fresco Фреска
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5325,3 +5325,5 @@ theme Appearance Utseende
|
||||
Water Paper Vått papper
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Fresk…
|
||||
Fresco Fresk
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4964,3 +4964,5 @@ lighting Light Світло
|
||||
Water Paper Мокрий папір
|
||||
Ruby… Рубі…
|
||||
Ruby Рубі
|
||||
Fresco… Фреска…
|
||||
Fresco Фреска
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 733 and column 40.
|
@@ -4964,3 +4964,5 @@ theme Appearance Giao diện
|
||||
Water Paper Giấy ướt
|
||||
Ruby… Ruby…
|
||||
Ruby Ruby
|
||||
Fresco… Bích họa…
|
||||
Fresco Bích họa
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 4021 and column 10.
|
@@ -5208,3 +5208,5 @@ lighting Light 光源
|
||||
Water Paper 水彩画纸
|
||||
Ruby… 注音…
|
||||
Ruby 注音
|
||||
Fresco… 壁画…
|
||||
Fresco 壁画
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5003,3 +5003,5 @@ lighting Light 光源
|
||||
Water Paper 水彩畫紙
|
||||
Ruby… 注音…
|
||||
Ruby 注音
|
||||
Fresco… 壁畫…
|
||||
Fresco 壁畫
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -93,6 +93,7 @@ fn effect_menu_lists_the_artistic_filters_before_blur() {
|
||||
"Cutout…",
|
||||
"Dry Brush…",
|
||||
"Film Grain…",
|
||||
"Fresco…",
|
||||
"Neon Glow…",
|
||||
"Paint Daubs…",
|
||||
"Palette Knife…",
|
||||
@@ -107,7 +108,7 @@ fn effect_menu_lists_the_artistic_filters_before_blur() {
|
||||
);
|
||||
assert!(artistic.iter().all(|e| e.command.as_deref() == Some("effect.dialog")));
|
||||
assert_eq!(artistic[2].params, json!({"effect": "artistic.dryBrush"}));
|
||||
assert_eq!(artistic[4].params, json!({"effect": "artistic.neonGlow"}));
|
||||
assert_eq!(artistic[5].params, json!({"effect": "artistic.neonGlow"}));
|
||||
let at = |name: &str| entries.iter().position(|e| e.path == ["Effect", name]).unwrap();
|
||||
assert!(at("Artistic") < at("Blur"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user