mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
G2: Effect › Artistic › Palette Knife raster filter
Squashed from #3038 onto main.
This commit is contained in:
@@ -148,6 +148,7 @@ fn lengths_of(id: &str) -> Lengths {
|
||||
"stylize.innerGlow" | "stylize.outerGlow" => always(&["blur"]),
|
||||
"stylize.glowingEdges" => always(&["edgeWidth", "smoothness"]),
|
||||
"brushStrokes.accentedEdges" => always(&["edgeWidth"]),
|
||||
"artistic.paletteKnife" => always(&["strokeSize"]),
|
||||
"brushStrokes.angledStrokes" | "brushStrokes.crosshatch" | "brushStrokes.inkOutlines" => always(&["strokeLength"]),
|
||||
"brushStrokes.spatter" => always(&["sprayRadius"]),
|
||||
"brushStrokes.sprayedStrokes" => always(&["strokeLength", "sprayRadius"]),
|
||||
@@ -377,6 +378,13 @@ pub fn effect_catalog() -> Vec<EffectInfo> {
|
||||
"{glowSize: -24..24 (5; above 0 the light areas glow, below 0 the dark ones; farther from 0 spreads the glow wider), glowBrightness: 0..50 (15; a stronger glow over dimmer greys), color: \"#rrggbb\" (\"#4da6ff\"; the glow's colour)} redraws the object in greys lit by a coloured glow, keeping its coverage. Original visual approximation; chosen VectorCraft defaults.",
|
||||
json!({"glowSize": 5.0, "glowBrightness": 15.0, "color": "#4da6ff"}),
|
||||
),
|
||||
r(
|
||||
"artistic.paletteKnife",
|
||||
"Palette Knife…",
|
||||
ARTISTIC,
|
||||
"{strokeSize: 1..50 (10; length of the knife strokes in document units), strokeDetail: 1..3 (2; more detail keeps more of the original), softness: 0..10 (3; softens the strokes)} smears the object's colours with short angled knife strokes, keeping its coverage. Original visual approximation; chosen VectorCraft defaults.",
|
||||
json!({"strokeSize": 10.0, "strokeDetail": 2.0, "softness": 3.0}),
|
||||
),
|
||||
r(
|
||||
"artistic.plasticWrap",
|
||||
"Plastic Wrap…",
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
//! Effect › Artistic (Cutout, Dry Brush, Film Grain, Neon Glow, Plastic Wrap, Poster Edges, Smudge Stick, Sponge and
|
||||
//! Effect › Artistic (Cutout, Dry Brush, Film Grain, Neon Glow, Palette Knife, Plastic Wrap, Poster Edges, Smudge Stick, Sponge and
|
||||
//! Watercolor). Original filters built from
|
||||
//! public behaviour documentation:
|
||||
//! <https://helpx.adobe.com/illustrator/using/summary-effects.html> and
|
||||
//! <https://helpx.adobe.com/photoshop-elements/using/artistic-filters.html>.
|
||||
//! These are visual approximations, not reproductions of a proprietary algorithm.
|
||||
|
||||
use super::brushstrokes::stroke_reach;
|
||||
use std::f64::consts::TAU;
|
||||
|
||||
use super::brushstrokes::{Smear, mix, stroke_reach, unit, unpremultiply};
|
||||
use super::edges::sobel;
|
||||
use super::pixelate::{Place, cell, rand, value_noise};
|
||||
use super::texture::{luma, premultiply, straight};
|
||||
@@ -472,3 +474,52 @@ pub(super) fn dry_brush(px: &mut [[u8; 4]], w: usize, h: usize, space: &PixelSpa
|
||||
}
|
||||
px.copy_from_slice(&out);
|
||||
}
|
||||
|
||||
const SALT_KNIFE: u64 = 208;
|
||||
|
||||
/// How far Palette Knife reaches with strokes `stroke_size` long and Softness `softness` (0..10).
|
||||
pub(super) fn palette_knife_reach(stroke_size: f64, softness: f64) -> f64 {
|
||||
stroke_reach(stroke_size) + 3.0 * 0.35 * softness.clamp(0.0, 10.0) + 1.0
|
||||
}
|
||||
|
||||
/// Artistic › Palette Knife: the object repainted with short, angled knife strokes that smear its
|
||||
/// colours; `stroke_size` (1..50) sets their length, `stroke_detail` (1..3) keeps more of the
|
||||
/// original where it's higher, and `softness` (0..10) softens the strokes. Coverage is kept.
|
||||
pub(super) fn palette_knife(px: &mut [[u8; 4]], w: usize, h: usize, space: &PixelSpace, stroke_size: f64, stroke_detail: f64, softness: f64) {
|
||||
let Some(place) = Place::new(space, w, h) else { return };
|
||||
if !(stroke_size.is_finite() && stroke_detail.is_finite() && softness.is_finite()) {
|
||||
return;
|
||||
}
|
||||
let len = stroke_size.clamp(1.0, 50.0);
|
||||
let keep = ((stroke_detail.clamp(1.0, 3.0) - 1.0) / 2.0) as f32;
|
||||
let smear = Smear::new(px, w, h, &place, len);
|
||||
let row = (0.25 * smear.len).max(1.0);
|
||||
let cell = len * 0.35;
|
||||
let src = px.to_vec();
|
||||
place.each(px, |x, y, p| {
|
||||
if p[3] == 0 {
|
||||
return;
|
||||
}
|
||||
let q = place.at(x, y);
|
||||
let angle = TAU * value_noise(SALT_KNIFE, q.x / cell, q.y / cell);
|
||||
let dir = Vec2::new(angle.cos(), angle.sin());
|
||||
let pm = smear.stroke(SALT_KNIFE + 1, q, dir, row);
|
||||
let orig = unit(src.get(y * w + x).copied().unwrap_or([0; 4]));
|
||||
let coverage = orig[3];
|
||||
let (c, _) = unpremultiply(mix(orig, pm, 1.0 - keep));
|
||||
*p = premultiply(c, coverage);
|
||||
});
|
||||
let sigma = 0.35 * softness.clamp(0.0, 10.0) / place.px;
|
||||
if sigma > 0.0 {
|
||||
let (mut colour, alpha) = planes(px);
|
||||
let cover = alpha.clone();
|
||||
soften(&mut colour, &alpha, w, h, sigma);
|
||||
for (k, p) in px.iter_mut().enumerate() {
|
||||
if cover[k] == 0.0 {
|
||||
continue;
|
||||
}
|
||||
let c = [colour[0][k], colour[1][k], colour[2][k]];
|
||||
*p = premultiply(c, cover[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,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; 48] = [
|
||||
pub const PIXEL_EFFECTS: [&str; 49] = [
|
||||
"artistic.cutout",
|
||||
"artistic.dryBrush",
|
||||
"artistic.filmGrain",
|
||||
"artistic.neonGlow",
|
||||
"artistic.paletteKnife",
|
||||
"artistic.plasticWrap",
|
||||
"artistic.posterEdges",
|
||||
"artistic.smudgeStick",
|
||||
@@ -122,6 +123,10 @@ pub enum PixelFx {
|
||||
/// light areas (`size` above 0) or the dark ones (below 0), spread by |`size`| (-24..24), as
|
||||
/// strong as `brightness` (0..50).
|
||||
NeonGlow { size: f64, brightness: f64, colour: [f32; 3] },
|
||||
/// Artistic › Palette Knife: knife strokes `stroke_size` (1..50) long smear the colours;
|
||||
/// `stroke_detail` (1..3) keeps more original detail when higher; `softness` (0..10) softens
|
||||
/// the strokes.
|
||||
PaletteKnife { stroke_size: f64, stroke_detail: f64, softness: f64 },
|
||||
/// Artistic › Plastic Wrap: specular highlights as strong as `highlight` (0..20) on a relief
|
||||
/// wrinkled by `detail` (0..15) and softened by `smoothness` (1..15).
|
||||
PlasticWrap { highlight: f64, detail: f64, smoothness: f64 },
|
||||
@@ -307,6 +312,11 @@ pub(crate) fn parse(id: &str, p: &Value) -> Option<PixelFx> {
|
||||
brightness: num(p, "glowBrightness", 15.0).clamp(0.0, 50.0),
|
||||
colour: crate::raster::color_param(p, vectorcraft_doc::color::Color::rgb(0.3, 0.65, 1.0)).to_rgb(),
|
||||
},
|
||||
"artistic.paletteKnife" => PixelFx::PaletteKnife {
|
||||
stroke_size: num(p, "strokeSize", 10.0).clamp(1.0, 50.0),
|
||||
stroke_detail: num(p, "strokeDetail", 2.0).clamp(1.0, 3.0),
|
||||
softness: num(p, "softness", 3.0).clamp(0.0, 10.0),
|
||||
},
|
||||
"artistic.posterEdges" => PixelFx::PosterEdges {
|
||||
thickness: num(p, "edgeThickness", 2.0).clamp(0.0, 10.0),
|
||||
intensity: num(p, "edgeIntensity", 1.0).clamp(0.0, 10.0),
|
||||
@@ -523,6 +533,7 @@ impl PixelFx {
|
||||
PixelFx::SmartBlur { radius, .. } => radius,
|
||||
PixelFx::AccentedEdges { .. } => 0.0,
|
||||
// Strokes reach out of the object as far as they reach into it.
|
||||
PixelFx::PaletteKnife { stroke_size, softness, .. } => artistic::palette_knife_reach(stroke_size, softness),
|
||||
PixelFx::AngledStrokes { length, .. } | PixelFx::GraphicPen { length, .. } | PixelFx::InkOutlines { length, .. } => {
|
||||
brushstrokes::stroke_reach(length)
|
||||
}
|
||||
@@ -581,6 +592,7 @@ impl PixelFx {
|
||||
PixelFx::Watercolor { detail, .. } => Some(paint::watercolor_reach(detail)),
|
||||
PixelFx::AccentedEdges { width, smoothness, .. } => Some(brushstrokes::accent_reach(width, smoothness)),
|
||||
// The strokes, and the softened tones that choose them.
|
||||
PixelFx::PaletteKnife { stroke_size, softness, .. } => Some(artistic::palette_knife_reach(stroke_size, softness)),
|
||||
PixelFx::AngledStrokes { length, .. } | PixelFx::GraphicPen { length, .. } => {
|
||||
Some(brushstrokes::stroke_reach(length).max(brushstrokes::TONE_REACH))
|
||||
}
|
||||
@@ -651,6 +663,9 @@ impl PixelFx {
|
||||
PixelFx::Watercolor { detail, shadow, texture } => paint::watercolor(px, w, h, space, detail, shadow, texture),
|
||||
PixelFx::PlasticWrap { highlight, detail, smoothness } => artistic::plastic_wrap(px, w, h, space, highlight, detail, smoothness),
|
||||
PixelFx::NeonGlow { size, brightness, colour } => artistic::neon_glow(px, w, h, space, size, brightness, colour),
|
||||
PixelFx::PaletteKnife { stroke_size, stroke_detail, softness } => {
|
||||
artistic::palette_knife(px, w, h, space, stroke_size, stroke_detail, softness)
|
||||
}
|
||||
PixelFx::PosterEdges { thickness, intensity, posterization } => {
|
||||
artistic::poster_edges(px, w, h, space, thickness, intensity, posterization)
|
||||
}
|
||||
|
||||
@@ -2647,3 +2647,30 @@ fn artistic_filters_look_the_same_at_any_resolution() {
|
||||
assert!(diff < 12.0, "{id}: mean difference {diff}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn palette_knife_params_take_defaults_and_stay_in_range() {
|
||||
assert_eq!(fx("artistic.paletteKnife", json!({})), PixelFx::PaletteKnife { stroke_size: 10.0, stroke_detail: 2.0, softness: 3.0 });
|
||||
assert_eq!(
|
||||
fx("artistic.paletteKnife", json!({"strokeSize": 0, "strokeDetail": 0, "softness": 99})),
|
||||
PixelFx::PaletteKnife { stroke_size: 1.0, stroke_detail: 1.0, softness: 10.0 }
|
||||
);
|
||||
assert!(fx("artistic.paletteKnife", json!({})).outset(Rect::new(0.0, 0.0, 40.0, 30.0)) > 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn palette_knife_smears_a_ramp_and_keeps_coverage() {
|
||||
let (w, h) = (48, 24);
|
||||
let src = ramp(w, h);
|
||||
let mut out = src.clone();
|
||||
fx("artistic.paletteKnife", json!({"strokeSize": 20, "strokeDetail": 1, "softness": 0})).apply(&mut out, w, h, &space(w, h));
|
||||
assert_ne!(out, src);
|
||||
assert!(out.as_chunks::<4>().0.iter().zip(src.as_chunks::<4>().0).all(|(o, s)| o[3] == s[3]));
|
||||
let mut gentle = src.clone();
|
||||
fx("artistic.paletteKnife", json!({"strokeSize": 20, "strokeDetail": 3, "softness": 0})).apply(&mut gentle, w, h, &space(w, h));
|
||||
let mean = |buf: &Vec<u8>| {
|
||||
let n = buf.len() / 4;
|
||||
buf.as_chunks::<4>().0.iter().map(|p| f64::from(p[0])).sum::<f64>() / n as f64
|
||||
};
|
||||
assert!((mean(&gentle) - mean(&src)).abs() < (mean(&out) - mean(&src)).abs());
|
||||
}
|
||||
|
||||
@@ -31,11 +31,12 @@ const BRUSH_STROKES: [(&str, &str); 8] = [
|
||||
];
|
||||
|
||||
/// Effect › Artistic, at their defaults.
|
||||
const ARTISTIC: [(&str, &str); 9] = [
|
||||
const ARTISTIC: [(&str, &str); 10] = [
|
||||
("artistic.cutout", "{}"),
|
||||
("artistic.dryBrush", "{}"),
|
||||
("artistic.filmGrain", "{}"),
|
||||
("artistic.neonGlow", "{}"),
|
||||
("artistic.paletteKnife", "{}"),
|
||||
("artistic.plasticWrap", "{}"),
|
||||
("artistic.posterEdges", "{}"),
|
||||
("artistic.smudgeStick", "{}"),
|
||||
|
||||
@@ -4555,7 +4555,9 @@ lighting Light Светлина
|
||||
Dry Brush… Суха четка…
|
||||
Dry Brush Суха четка
|
||||
Neon Glow… Неоново сияние…
|
||||
Palette Knife… Нож за палитра…
|
||||
Neon Glow Неоново сияние
|
||||
Palette Knife Нож за палитра
|
||||
Poster Edges… Плакатни ръбове…
|
||||
Poster Edges Плакатни ръбове
|
||||
Levels Нива
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5054,7 +5054,9 @@ imageTrace Outline Obrys
|
||||
Dry Brush… Suchý štětec…
|
||||
Dry Brush Suchý štětec
|
||||
Neon Glow… Neonová záře…
|
||||
Palette Knife… Špachtle…
|
||||
Neon Glow Neonová záře
|
||||
Palette Knife Špachtle
|
||||
Poster Edges… Plakátové okraje…
|
||||
Poster Edges Plakátové okraje
|
||||
Levels Úrovně
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5178,10 +5178,12 @@ swatch Bright Violet Kraftig violet
|
||||
Cutout… Udklip…
|
||||
Dry Brush… Tør pensel…
|
||||
Neon Glow… Neonglød…
|
||||
Palette Knife… Paletkniv…
|
||||
Poster Edges… Plakatkanter…
|
||||
Cutout Udklip
|
||||
Dry Brush Tør pensel
|
||||
Neon Glow Neonglød
|
||||
Palette Knife Paletkniv
|
||||
Poster Edges Plakatkanter
|
||||
Apply Data Set Anvend datasæt
|
||||
Cancel Pattern Editing Annullér redigering af mønster
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4642,7 +4642,9 @@ lighting Light Licht
|
||||
Dry Brush… Trockenpinsel…
|
||||
Dry Brush Trockenpinsel
|
||||
Neon Glow… Neonglühen…
|
||||
Palette Knife… Palettenmesser…
|
||||
Neon Glow Neonglühen
|
||||
Palette Knife Palettenmesser
|
||||
Poster Edges… Posterkanten…
|
||||
Poster Edges Posterkanten
|
||||
Levels Stufen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2264,7 +2264,9 @@ lighting Light Φως
|
||||
Dry Brush… Ξηρό πινέλο…
|
||||
Dry Brush Ξηρό πινέλο
|
||||
Neon Glow… Λάμψη νέον…
|
||||
Palette Knife… Μαχαίρι παλέτας…
|
||||
Neon Glow Λάμψη νέον
|
||||
Palette Knife Μαχαίρι παλέτας
|
||||
Poster Edges… Άκρες αφίσας…
|
||||
Poster Edges Άκρες αφίσας
|
||||
Levels Επίπεδα
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2031 and column 19.
|
@@ -4642,7 +4642,9 @@ lighting Light Luz
|
||||
Dry Brush… Pincel seco…
|
||||
Dry Brush Pincel seco
|
||||
Neon Glow… Resplandor de neón…
|
||||
Palette Knife… Espátula…
|
||||
Neon Glow Resplandor de neón
|
||||
Palette Knife Espátula
|
||||
Poster Edges… Bordes de póster…
|
||||
Poster Edges Bordes de póster
|
||||
Levels Niveles
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4949,7 +4949,9 @@ imageTrace Outline Ääriviiva
|
||||
Dry Brush… Kuiva sivellin…
|
||||
Dry Brush Kuiva sivellin
|
||||
Neon Glow… Neonhehku…
|
||||
Palette Knife… Palettiveitsi…
|
||||
Neon Glow Neonhehku
|
||||
Palette Knife Palettiveitsi
|
||||
Poster Edges… Julisteen reunat…
|
||||
Poster Edges Julisteen reunat
|
||||
Levels Tasot
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4652,7 +4652,9 @@ lighting Light Lumière
|
||||
Dry Brush… Pinceau sec…
|
||||
Dry Brush Pinceau sec
|
||||
Neon Glow… Néon…
|
||||
Palette Knife… Couteau à palette…
|
||||
Neon Glow Néon
|
||||
Palette Knife Couteau à palette
|
||||
Poster Edges… Bords d’affiche…
|
||||
Poster Edges Bords d’affiche
|
||||
Levels Niveaux
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1585,7 +1585,9 @@ file-filter Templates Sablonok
|
||||
Dry Brush… Száraz ecset…
|
||||
Dry Brush Száraz ecset
|
||||
Neon Glow… Neonfény…
|
||||
Palette Knife… Palettakés…
|
||||
Neon Glow Neonfény
|
||||
Palette Knife Palettakés
|
||||
Poster Edges… Poszterszélek…
|
||||
Poster Edges Poszterszélek
|
||||
Levels Szintek
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5178,10 +5178,12 @@ swatch Bright Violet Violet cerah
|
||||
Cutout… Potongan…
|
||||
Dry Brush… Kuas kering…
|
||||
Neon Glow… Pendar neon…
|
||||
Palette Knife… Pisau palet…
|
||||
Poster Edges… Tepi poster…
|
||||
Cutout Potongan
|
||||
Dry Brush Kuas kering
|
||||
Neon Glow Pendar neon
|
||||
Palette Knife Pisau palet
|
||||
Poster Edges Tepi poster
|
||||
Apply Data Set Terapkan set data
|
||||
Cancel Pattern Editing Batalkan pengeditan pola
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 3801 and column 19.
|
@@ -4684,7 +4684,9 @@ lighting Light Luce
|
||||
Dry Brush… Pennello secco…
|
||||
Dry Brush Pennello secco
|
||||
Neon Glow… Bagliore neon…
|
||||
Palette Knife… Spatola…
|
||||
Neon Glow Bagliore neon
|
||||
Palette Knife Spatola
|
||||
Poster Edges… Bordi poster…
|
||||
Poster Edges Bordi poster
|
||||
Levels Livelli
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4723,7 +4723,9 @@ lighting Light ライト
|
||||
Dry Brush… ドライブラシ…
|
||||
Dry Brush ドライブラシ
|
||||
Neon Glow… ネオングロー…
|
||||
Palette Knife… パレットナイフ…
|
||||
Neon Glow ネオングロー
|
||||
Palette Knife パレットナイフ
|
||||
Poster Edges… ポスターエッジ…
|
||||
Poster Edges ポスターエッジ
|
||||
Levels レベル数
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5077,7 +5077,9 @@ imageTrace Outline კონტური
|
||||
Move Slice ნაჭრის გადაადგილება
|
||||
Move Type on a Path ტრაექტორიაზე ტექსტის გადაადგილება
|
||||
Neon Glow ნეონის ნათება
|
||||
Palette Knife პალეტის დანა
|
||||
Neon Glow… ნეონის ნათება…
|
||||
Palette Knife… პალეტის დანა…
|
||||
New Artboard Options… ახალი სამუშაო დაფის პარამეტრები…
|
||||
New Guide ახალი დამხმარე ხაზი
|
||||
Next Artboard შემდეგი სამუშაო დაფა
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4647,7 +4647,9 @@ lighting Light 광원
|
||||
Dry Brush… 드라이 브러시…
|
||||
Dry Brush 드라이 브러시
|
||||
Neon Glow… 네온 글로…
|
||||
Palette Knife… 팔레트 나이프…
|
||||
Neon Glow 네온 글로
|
||||
Palette Knife 팔레트 나이프
|
||||
Poster Edges… 포스터 가장자리…
|
||||
Poster Edges 포스터 가장자리
|
||||
Levels 레벨 수
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5189,10 +5189,12 @@ swatch Bright Violet Felviolet
|
||||
Cutout… Knipsel…
|
||||
Dry Brush… Droog penseel…
|
||||
Neon Glow… Neongloed…
|
||||
Palette Knife… Paletmes…
|
||||
Poster Edges… Posterranden…
|
||||
Cutout Knipsel
|
||||
Dry Brush Droog penseel
|
||||
Neon Glow Neongloed
|
||||
Palette Knife Paletmes
|
||||
Poster Edges Posterranden
|
||||
Apply Data Set Gegevensset toepassen
|
||||
Cancel Pattern Editing Patroon bewerken annuleren
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4887,7 +4887,9 @@ imageTrace Outline Kontur
|
||||
Dry Brush… Suchy pędzel…
|
||||
Dry Brush Suchy pędzel
|
||||
Neon Glow… Neonowa poświata…
|
||||
Palette Knife… Szpachel…
|
||||
Neon Glow Neonowa poświata
|
||||
Palette Knife Szpachel
|
||||
Poster Edges… Krawędzie plakatu…
|
||||
Poster Edges Krawędzie plakatu
|
||||
Levels Poziomy
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4044,7 +4044,9 @@ axis Both Ambos
|
||||
Dry Brush… Pincel seco…
|
||||
Dry Brush Pincel seco
|
||||
Neon Glow… Brilho neon…
|
||||
Palette Knife… Espátula…
|
||||
Neon Glow Brilho neon
|
||||
Palette Knife Espátula
|
||||
Poster Edges… Bordas de pôster…
|
||||
Poster Edges Bordas de pôster
|
||||
Levels Níveis
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4680,7 +4680,9 @@ lighting Light Свет
|
||||
Dry Brush… Сухая кисть…
|
||||
Dry Brush Сухая кисть
|
||||
Neon Glow… Неоновое свечение…
|
||||
Palette Knife… Нож для палитры…
|
||||
Neon Glow Неоновое свечение
|
||||
Palette Knife Нож для палитры
|
||||
Poster Edges… Края плаката…
|
||||
Poster Edges Края плаката
|
||||
Levels Уровни
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4561,7 +4561,9 @@ lighting Light Ljus
|
||||
Dry Brush… Torr pensel…
|
||||
Dry Brush Torr pensel
|
||||
Neon Glow… Neonsken…
|
||||
Palette Knife… Palettkniv…
|
||||
Neon Glow Neonsken
|
||||
Palette Knife Palettkniv
|
||||
Poster Edges… Affischkanter…
|
||||
Poster Edges Affischkanter
|
||||
Levels Nivåer
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4664,7 +4664,9 @@ lighting Light Світло
|
||||
Dry Brush… Суха кисть…
|
||||
Dry Brush Суха кисть
|
||||
Neon Glow… Неонове сяйво…
|
||||
Palette Knife… Ніж палітри…
|
||||
Neon Glow Неонове сяйво
|
||||
Palette Knife Ніж палітри
|
||||
Poster Edges… Плакатні краї…
|
||||
Poster Edges Плакатні краї
|
||||
Levels Рівні
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 726 and column 40.
|
@@ -1273,7 +1273,9 @@
|
||||
Dry Brush… Cọ khô…
|
||||
Dry Brush Cọ khô
|
||||
Neon Glow… Ánh neon…
|
||||
Palette Knife… Dao palette…
|
||||
Neon Glow Ánh neon
|
||||
Palette Knife Dao palette
|
||||
Poster Edges… Viền áp phích…
|
||||
Poster Edges Viền áp phích
|
||||
Levels Số mức
|
||||
|
||||
|
@@ -4948,7 +4948,9 @@ lighting Light 光源
|
||||
Cutout 剪纸
|
||||
Dry Brush 干画笔
|
||||
Neon Glow… 霓虹灯光…
|
||||
Palette Knife… 调色刀…
|
||||
Neon Glow 霓虹灯光
|
||||
Palette Knife 调色刀
|
||||
Poster Edges… 海报边缘…
|
||||
Poster Edges 海报边缘
|
||||
Levels 色阶数
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4754,7 +4754,9 @@ lighting Light 光源
|
||||
Cutout 剪紙
|
||||
Dry Brush 乾畫筆
|
||||
Neon Glow… 霓虹光…
|
||||
Palette Knife… 調色刀…
|
||||
Neon Glow 霓虹光
|
||||
Palette Knife 調色刀
|
||||
Poster Edges… 海報邊緣…
|
||||
Poster Edges 海報邊緣
|
||||
Levels 色階數
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -88,7 +88,18 @@ fn effect_menu_lists_the_artistic_filters_before_blur() {
|
||||
let labels: Vec<&str> = artistic.iter().map(|e| e.label.as_str()).collect();
|
||||
assert_eq!(
|
||||
labels,
|
||||
["Cutout…", "Dry Brush…", "Film Grain…", "Neon Glow…", "Plastic Wrap…", "Poster Edges…", "Smudge Stick…", "Sponge…", "Watercolor…"]
|
||||
[
|
||||
"Cutout…",
|
||||
"Dry Brush…",
|
||||
"Film Grain…",
|
||||
"Neon Glow…",
|
||||
"Palette Knife…",
|
||||
"Plastic Wrap…",
|
||||
"Poster Edges…",
|
||||
"Smudge Stick…",
|
||||
"Sponge…",
|
||||
"Watercolor…"
|
||||
]
|
||||
);
|
||||
assert!(artistic.iter().all(|e| e.command.as_deref() == Some("effect.dialog")));
|
||||
assert_eq!(artistic[1].params, json!({"effect": "artistic.dryBrush"}));
|
||||
|
||||
Reference in New Issue
Block a user