mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 19:26:56 -04:00
M9.2: replace Find Edges with Glowing Edges
This commit is contained in:
1 parent
2d371849df
commit
11aaf816d0
15 files changed
+99
-38
No files matched your search
+2
-2
@@ -57,7 +57,7 @@ Ordered by how much each gap blocks someone from switching. Sizes are one-agent
|
||||
Pixelate, Sketch, Stylize, Texture, Video) and the Effect Gallery. The pixel-filter pipeline is in place
|
||||
(`vectorcraft_effects::pixel`: the object rendered offscreen, filtered in stack order with Gaussian Blur and
|
||||
Feather, cached while panning, images in PDF/SVG/Expand Appearance) with Blur › Radial Blur and Smart Blur
|
||||
(Normal mode only), Sharpen › Unsharp Mask and Stylize › Find Edges; each new filter is now one function, a catalogue row, menu and
|
||||
(Normal mode only), Sharpen › Unsharp Mask and Stylize › Glowing Edges; each new filter is now one function, a catalogue row, menu and
|
||||
translations. Parallelizes well across agents. 26–40 h.
|
||||
3. **3D and Materials:** Extrude & Bevel, Revolve, Inflate and Rotate with lighting and materials, using a software
|
||||
renderer in its own crate (layering allows it below L6), with output in SVG/PDF as rasters or projected vectors.
|
||||
@@ -219,7 +219,7 @@ about 1–1.5 agent-hours each, so the other rows (estimated on the older scale)
|
||||
| Strokes, brushes, width profiles | 5 | 88% | brush options depth, brush libraries (generated in code), brushes driven by pen tilt, bearing and barrel rotation (6D art pens) | 12–20 |
|
||||
| Appearance, transparency, graphic styles, masks | 5 | 98% | raster effect reach in preview bounds (flattener presets apply in PDF, EPS and print) | 1–2 |
|
||||
| Live vector effects | 5 | 85% | Outline Object, Pathfinder Hard/Soft Mix and Trap, SVG Filters | 6–10 |
|
||||
| Raster effects (Effect Gallery, Document Raster Effects Settings) | 4 | 25% | ~51 Photoshop-style filters (Artistic, Brush Strokes, Distort, Pixelate, Sketch, Stylize, Texture, Video), Smart Blur's Edge Only / Overlay Edge modes and the Effect Gallery; Document Raster Effects Settings, raster effects in PDF, the pixel-filter pipeline, Radial Blur, Smart Blur, Unsharp Mask and Find Edges are done | 26–40 |
|
||||
| Raster effects (Effect Gallery, Document Raster Effects Settings) | 4 | 25% | ~51 Photoshop-style filters (Artistic, Brush Strokes, Distort, Pixelate, Sketch, Stylize, Texture, Video), Smart Blur's Edge Only / Overlay Edge modes and the Effect Gallery; Document Raster Effects Settings, raster effects in PDF, the pixel-filter pipeline, Radial Blur, Smart Blur, Unsharp Mask and Glowing Edges are done | 26–40 |
|
||||
| 3D and Materials | 4 | 0% | Extrude & Bevel, Revolve, Inflate, Rotate, lighting, materials (software renderer) | 50–80 |
|
||||
| Type core | 9 | 80% | Middle Eastern features beyond bidi layout and Paragraph Direction (Character Direction, digit types, kashidas, the Middle Eastern composers, editable bidirectional SVG text, a split caret where directions meet); Hyphenation… and Justification… options (Every-line Composer for justified and ragged text, per object, is done; it is tuned by eye, not yet compared side by side with Illustrator; mixed type sizes in a paragraph still break single-line), Optical Margin Alignment, paragraph spacing limit for vertically justified area type, hidden characters, paragraph attributes in the Type tool's copy and paste (the characters keep their styles, the paragraphs take the destination's), mixed-value display in the Paragraph panel for a selection across differing paragraphs, Transform Again after a type-area resize (it scales the type), partial selection of type-area anchors by marquee | 14–19 |
|
||||
| Type advanced | 4 | 50% | CJK composition for vertical type (ruby, mojikumi beyond Line-end Punctuation Half Width — the other sets (and their paragraph-start bracket and indent rules), custom kinsoku sets (beyond Hard, Soft and None) and the Mojikumi Settings dialog —, proportional vertical metrics, manual tate-chu-yoko), variable font axis sliders (named instances are styles), tab leaders, spell check (open dictionary), Touch Type, Retype; vertical point/area/path type and Type Orientation have initial support (beyond parity, not scored: inline symbols in text) | 20–28 |
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! - **Geometry effects** (Distort & Transform, Path, Convert to Shape, Round Corners, Scribble,
|
||||
//! Warp) rewrite a path: [`apply_geometry`] evaluates them in stack order.
|
||||
//! - **Raster effects** (Drop Shadow, Inner/Outer Glow, Feather, Gaussian Blur, and the
|
||||
//! Photoshop-style filters of [`pixel`]: Radial Blur, Smart Blur, Unsharp Mask) are described by
|
||||
//! Photoshop-style filters of [`pixel`]: Radial Blur, Smart Blur, Unsharp Mask and Glowing Edges) are described by
|
||||
//! [`raster_effects`] and painted by the renderer; [`outset`] says how far they reach beyond
|
||||
//! the geometry.
|
||||
//! - **Stroke geometry** ([`stroke`]): arrowheads, dash patterns and width profiles, shared by the
|
||||
@@ -125,6 +125,7 @@ fn lengths_of(id: &str) -> Lengths {
|
||||
"stylize.scribble" => always(&["overlap", "strokeWidth", "spacing", "variation"]),
|
||||
"stylize.dropShadow" => always(&["x", "y", "blur"]),
|
||||
"stylize.innerGlow" | "stylize.outerGlow" => always(&["blur"]),
|
||||
"stylize.glowingEdges" => always(&["edgeWidth", "smoothness"]),
|
||||
_ => Lengths::default(),
|
||||
}
|
||||
}
|
||||
@@ -290,7 +291,13 @@ pub fn effect_catalog() -> Vec<EffectInfo> {
|
||||
"{amount: % 1..500 (50), radius: pt 0.1..250 (1; σ of the blur edges are found against), threshold: levels 0..255 (0; smaller differences are left alone)}",
|
||||
json!({"amount": 50.0, "radius": 1.0, "threshold": 0.0}),
|
||||
),
|
||||
r("stylize.findEdges", "Find Edges", STYLIZE, "{} replaces colour with a Sobel edge map while preserving transparency", json!({})),
|
||||
r(
|
||||
"stylize.glowingEdges",
|
||||
"Glowing Edges…",
|
||||
STYLIZE,
|
||||
"{edgeWidth: pt 1..14 (2), edgeBrightness: 0..20 (6), smoothness: pt 1..15 (5)} finds alpha-weighted Sobel edges and draws bright coloured outlines on black",
|
||||
json!({"edgeWidth": 2.0, "edgeBrightness": 6.0, "smoothness": 5.0}),
|
||||
),
|
||||
];
|
||||
v.extend([
|
||||
g(
|
||||
|
||||
@@ -1,30 +1,38 @@
|
||||
//! Stylize › Find Edges.
|
||||
//! Stylize › Glowing Edges.
|
||||
|
||||
use super::Px16;
|
||||
use super::blur_plane;
|
||||
|
||||
/// Convert premultiplied RGBA pixels to a Sobel edge map in place.
|
||||
pub(super) fn find(px: &mut [[u8; 4]], w: usize, h: usize) {
|
||||
if w < 3 || h < 3 || w.checked_mul(h) != Some(px.len()) {
|
||||
/// Find Sobel edges using alpha-weighted straight colour, smooth and expand them, then draw
|
||||
/// coloured outlines on black. Samples outside the raster are transparent.
|
||||
pub(super) fn glow(px: &mut [[u8; 4]], w: usize, h: usize, width: f64, brightness: f64, smoothness: f64) {
|
||||
if w == 0 || h == 0 || w.checked_mul(h) != Some(px.len()) {
|
||||
return;
|
||||
}
|
||||
let src: Vec<Px16> = px.iter().map(|p| p.map(u16::from)).collect();
|
||||
let luminance = |x: usize, y: usize| -> f32 {
|
||||
src.get(y * w + x).map_or(0.0, |p| {
|
||||
(0.2126 * f32::from(p[0]) + 0.7152 * f32::from(p[1]) + 0.0722 * f32::from(p[2])) / 257.0
|
||||
})
|
||||
let src = px.to_vec();
|
||||
let signal = |x: isize, y: isize| -> f32 {
|
||||
if x < 0 || y < 0 { return 0.0; }
|
||||
let Some(p) = src.get(y as usize * w + x as usize) else { return 0.0 };
|
||||
let alpha = f32::from(p[3]) / 255.0;
|
||||
let straight = if alpha > 0.0 { [f32::from(p[0]) / 255.0 / alpha, f32::from(p[1]) / 255.0 / alpha, f32::from(p[2]) / 255.0 / alpha] } else { [0.0; 3] };
|
||||
(0.2126 * straight[0] + 0.7152 * straight[1] + 0.0722 * straight[2]) * alpha
|
||||
};
|
||||
for y in 1..h - 1 {
|
||||
for x in 1..w - 1 {
|
||||
let gx = -luminance(x - 1, y - 1) + luminance(x + 1, y - 1)
|
||||
- 2.0 * luminance(x - 1, y) + 2.0 * luminance(x + 1, y)
|
||||
- luminance(x - 1, y + 1) + luminance(x + 1, y + 1);
|
||||
let gy = -luminance(x - 1, y - 1) - 2.0 * luminance(x, y - 1) - luminance(x + 1, y - 1)
|
||||
+ luminance(x - 1, y + 1) + 2.0 * luminance(x, y + 1) + luminance(x + 1, y + 1);
|
||||
let edge = gx.hypot(gy).clamp(0.0, 255.0) as u8;
|
||||
if let Some(out) = px.get_mut(y * w + x) {
|
||||
let alpha = out[3];
|
||||
*out = [edge.min(alpha), edge.min(alpha), edge.min(alpha), alpha];
|
||||
}
|
||||
let mut edges = vec![0.0f32; px.len()];
|
||||
for y in 0..h {
|
||||
for x in 0..w {
|
||||
let x = x as isize;
|
||||
let y = y as isize;
|
||||
let gx = -signal(x - 1, y - 1) + signal(x + 1, y - 1) - 2.0 * signal(x - 1, y) + 2.0 * signal(x + 1, y) - signal(x - 1, y + 1) + signal(x + 1, y + 1);
|
||||
let gy = -signal(x - 1, y - 1) - 2.0 * signal(x, y - 1) - signal(x + 1, y - 1) + signal(x - 1, y + 1) + 2.0 * signal(x, y + 1) + signal(x + 1, y + 1);
|
||||
if let Some(edge) = edges.get_mut(y as usize * w + x as usize) { *edge = gx.hypot(gy).clamp(0.0, 1.0); }
|
||||
}
|
||||
}
|
||||
blur_plane(&mut edges, w, h, smoothness.max(0.0));
|
||||
if width > 0.5 { blur_plane(&mut edges, w, h, width * 0.5); }
|
||||
for (out, (original, edge)) in px.iter_mut().zip(src.iter().zip(edges)) {
|
||||
let alpha = f32::from(original[3]) / 255.0;
|
||||
let glow = (edge * brightness as f32 / 6.0).clamp(0.0, 1.0);
|
||||
let straight = if original[3] > 0 { [f32::from(original[0]) / 255.0 / alpha.max(1e-6), f32::from(original[1]) / 255.0 / alpha.max(1e-6), f32::from(original[2]) / 255.0 / alpha.max(1e-6)] } else { [1.0, 1.0, 1.0] };
|
||||
let a = alpha.max(glow);
|
||||
*out = [(straight[0] * glow * a * 255.0).round().clamp(0.0, 255.0) as u8, (straight[1] * glow * a * 255.0).round().clamp(0.0, 255.0) as u8, (straight[2] * glow * a * 255.0).round().clamp(0.0, 255.0) as u8, (a * 255.0).round() as u8];
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Photoshop-style raster effects (Effect › Blur › Radial Blur and Smart Blur, Sharpen › Unsharp
|
||||
//! Mask, and Stylize › Find Edges): filters over premultiplied RGBA8 pixels.
|
||||
//! Mask, and Stylize › Glowing Edges): filters over premultiplied RGBA8 pixels.
|
||||
//!
|
||||
//! - Every distance is in document units (points) and becomes pixels through the raster's
|
||||
//! [`PixelSpace::px`], so an effect looks the same at any zoom and at any Document Raster Effects
|
||||
@@ -18,7 +18,7 @@ use vectorcraft_geom::{Affine, Point, Rect};
|
||||
use crate::util::{num, text};
|
||||
|
||||
/// The Photoshop-style effect ids (all raster effects, see [`crate::is_raster`]).
|
||||
pub const PIXEL_EFFECTS: [&str; 4] = ["blur.radial", "blur.smart", "sharpen.unsharpMask", "stylize.findEdges"];
|
||||
pub const PIXEL_EFFECTS: [&str; 4] = ["blur.radial", "blur.smart", "sharpen.unsharpMask", "stylize.glowingEdges"];
|
||||
|
||||
/// A Photoshop-style raster effect with its parameters read and clamped to their ranges. Lengths
|
||||
/// are in document units.
|
||||
@@ -34,8 +34,8 @@ pub enum PixelFx {
|
||||
/// Sharpen › Unsharp Mask: colours pushed away from a Gaussian blur of σ = `radius` by `amount`
|
||||
/// (1 = 100 %), where they differ from it by at least `threshold` levels.
|
||||
UnsharpMask { amount: f64, radius: f64, threshold: f64 },
|
||||
/// Stylize › Find Edges: replace colour with a Sobel edge map while preserving opacity.
|
||||
FindEdges,
|
||||
/// Stylize › Glowing Edges: bright coloured Sobel outlines on black.
|
||||
GlowingEdges { width: f64, brightness: f64, smoothness: f64 },
|
||||
}
|
||||
|
||||
/// Where a raster's pixels lie in the document.
|
||||
@@ -72,7 +72,11 @@ pub(crate) fn parse(id: &str, p: &Value) -> Option<PixelFx> {
|
||||
radius: num(p, "radius", 1.0).clamp(0.1, 250.0),
|
||||
threshold: num(p, "threshold", 0.0).clamp(0.0, 255.0),
|
||||
},
|
||||
"stylize.findEdges" => PixelFx::FindEdges,
|
||||
"stylize.glowingEdges" => PixelFx::GlowingEdges {
|
||||
width: num(p, "edgeWidth", 2.0).clamp(1.0, 14.0),
|
||||
brightness: num(p, "edgeBrightness", 6.0).clamp(0.0, 20.0),
|
||||
smoothness: num(p, "smoothness", 5.0).clamp(1.0, 15.0),
|
||||
},
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@@ -89,7 +93,7 @@ impl PixelFx {
|
||||
PixelFx::RadialBlur { amount, zoom: true, .. } => far * (blur::zoom_extent(amount).exp() - 1.0),
|
||||
PixelFx::SmartBlur { radius, .. } => radius,
|
||||
PixelFx::UnsharpMask { .. } => 0.0,
|
||||
PixelFx::FindEdges => 0.0,
|
||||
PixelFx::GlowingEdges { width, smoothness, .. } => width.max(smoothness * 3.0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +104,7 @@ impl PixelFx {
|
||||
PixelFx::RadialBlur { .. } => None,
|
||||
PixelFx::SmartBlur { radius, .. } => Some(radius),
|
||||
PixelFx::UnsharpMask { radius, .. } => Some(3.0 * radius),
|
||||
PixelFx::FindEdges => Some(1.0),
|
||||
PixelFx::GlowingEdges { width, smoothness, .. } => Some(width.max(smoothness * 3.0)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +117,7 @@ impl PixelFx {
|
||||
PixelFx::RadialBlur { amount, zoom, passes } => blur::radial(px, w, h, space, amount, zoom, passes),
|
||||
PixelFx::SmartBlur { radius, threshold, samples } => blur::smart(px, w, h, to_px(radius), threshold, samples),
|
||||
PixelFx::UnsharpMask { amount, radius, threshold } => sharpen::unsharp(px, w, h, amount, to_px(radius), threshold),
|
||||
PixelFx::FindEdges => edges::find(px, w, h),
|
||||
PixelFx::GlowingEdges { width, brightness, smoothness } => edges::glow(px, w, h, to_px(width), brightness, to_px(smoothness)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ fn params_take_defaults_and_stay_in_range() {
|
||||
fx("sharpen.unsharpMask", json!({"amount": 1e9, "radius": 0, "threshold": 1e9})),
|
||||
PixelFx::UnsharpMask { amount: 5.0, radius: 0.1, threshold: 255.0 }
|
||||
);
|
||||
assert_eq!(fx("stylize.findEdges", json!({})), PixelFx::FindEdges);
|
||||
assert_eq!(fx("stylize.glowingEdges", json!({})), PixelFx::GlowingEdges { width: 2.0, brightness: 6.0, smoothness: 5.0 });
|
||||
for id in PIXEL_EFFECTS {
|
||||
assert!(crate::is_raster(id) && crate::effect_info(id).is_some_and(|e| e.raster), "{id}");
|
||||
}
|
||||
@@ -122,13 +122,13 @@ fn every_effect_is_deterministic() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_edges_detects_a_boundary_and_preserves_alpha() {
|
||||
fn glowing_edges_draw_a_bright_outline_and_preserve_premultiplication() {
|
||||
let (w, h) = (9, 9);
|
||||
let src = image(w, h, |x, _| if x < 4 { [0, 0, 0, 200] } else { [200, 200, 200, 200] });
|
||||
let mut out = src.clone();
|
||||
fx("stylize.findEdges", json!({})).apply(&mut out, w, h, &space(w, h));
|
||||
fx("stylize.glowingEdges", json!({"edgeWidth": 1, "smoothness": 1, "edgeBrightness": 20})).apply(&mut out, w, h, &space(w, h));
|
||||
assert!(at(&out, w, 3, 4)[0] > 0 || at(&out, w, 4, 4)[0] > 0);
|
||||
assert!(out.chunks_exact(4).all(|p| p[3] == 200 && p[0] <= p[3] && p[1] <= p[3] && p[2] <= p[3]));
|
||||
assert!(out.chunks_exact(4).all(|p| p[0] <= p[3] && p[1] <= p[3] && p[2] <= p[3]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
# back to English. Left in English on purpose (`MENU_KEEP_AS_IS` in the tests): the product name,
|
||||
# language names, OpenType, the built-in workspace names and the bracketed perspective grid preset
|
||||
# names.
|
||||
Glowing Edges… Zářící okraje…
|
||||
About VectorCraft O aplikaci VectorCraft
|
||||
Align to Path Zarovnat k cestě
|
||||
Cut Path at Selected Anchor Points Rozdělit cestu ve vybraných kotevních bodech
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -12,6 +12,11 @@
|
||||
# tested). Left in English on purpose (`MENU_KEEP_AS_IS` in the tests): the product name, language
|
||||
# names, OpenType, the built-in workspace names and the bracketed perspective grid preset names.
|
||||
# Photoshop-style raster effects (Effect menu, their dialogs).
|
||||
Glowing Edges… Bordes resplandecientes…
|
||||
Glowing Edges Bordes resplandecientes
|
||||
Edge Width Ancho del borde
|
||||
Edge Brightness Brillo del borde
|
||||
Smoothness Suavizado
|
||||
Radial Blur… Desenfoque radial…
|
||||
Smart Blur… Desenfoque inteligente…
|
||||
Sharpen Enfocar
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -13,6 +13,11 @@
|
||||
# tested). Left in English on purpose (`MENU_KEEP_AS_IS` in the tests): the product name, language
|
||||
# names, OpenType, the built-in workspace names and the bracketed perspective grid preset names.
|
||||
# Photoshop-style raster effects (Effect menu, their dialogs).
|
||||
Glowing Edges… Bords lumineux…
|
||||
Glowing Edges Bords lumineux
|
||||
Edge Width Largeur du bord
|
||||
Edge Brightness Luminosité du bord
|
||||
Smoothness Lissage
|
||||
Radial Blur… Flou radial…
|
||||
Smart Blur… Flou intelligent…
|
||||
Sharpen Netteté
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -12,6 +12,11 @@
|
||||
# tested). Left in English on purpose (`MENU_KEEP_AS_IS` in the tests): the product name, language
|
||||
# names, OpenType, the built-in workspace names and the bracketed perspective grid preset names.
|
||||
# Photoshop-style raster effects (Effect menu, their dialogs).
|
||||
Glowing Edges… Bordi luminosi…
|
||||
Glowing Edges Bordi luminosi
|
||||
Edge Width Larghezza bordo
|
||||
Edge Brightness Luminosità bordo
|
||||
Smoothness Uniformità
|
||||
Radial Blur… Sfocatura radiale…
|
||||
Smart Blur… Sfocatura intelligente…
|
||||
Sharpen Nitidezza
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4,6 +4,11 @@
|
||||
# Clean-room: menu and feature names follow the names Japanese users of vector illustration
|
||||
# software know, written from the meaning of VectorCraft's English labels; no other application's
|
||||
# Japanese localisation was copied. Toggles read as their action (「…を表示」「…を隠す」).
|
||||
Glowing Edges… エッジの光彩…
|
||||
Glowing Edges エッジの光彩
|
||||
Edge Width エッジの幅
|
||||
Edge Brightness エッジの明るさ
|
||||
Smoothness 滑らかさ
|
||||
#
|
||||
# Coverage: the whole interface — every menu string and every `tl!` literal (`complete_menus`,
|
||||
# tested) — and the status and error messages (`@msg` rows at the end, `COMPLETE_MESSAGES`, tested).
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -14,6 +14,7 @@
|
||||
# Brazilian Portuguese computing vocabulary (arquivo, camada, caminho, preenchimento, traçado,
|
||||
# pincel, amostra, mesa de trabalho ...), following common desktop-software conventions (commands
|
||||
# in the infinitive, menus as nouns); no proprietary localisation resource, string table or product
|
||||
Glowing Edges… Bordas brilhantes…
|
||||
# UI was consulted or copied; add entries the same way. Product and technology names (VectorCraft,
|
||||
# ArtCraft, SVG, OpenType, CMYK, Lab ...) stay in Latin letters; the trailing "…" of dialog
|
||||
# commands is kept.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -10,6 +10,11 @@
|
||||
# tested). Left in English on purpose (`MENU_KEEP_AS_IS` in the tests): the product name, language
|
||||
# names, OpenType, the built-in workspace names and the bracketed perspective grid preset names.
|
||||
# Photoshop-style raster effects (Effect menu, their dialogs).
|
||||
Glowing Edges… Светящиеся края…
|
||||
Glowing Edges Светящиеся края
|
||||
Edge Width Ширина края
|
||||
Edge Brightness Яркость края
|
||||
Smoothness Сглаживание
|
||||
Radial Blur… Радиальное размытие…
|
||||
Smart Blur… Умное размытие…
|
||||
Sharpen Резкость
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -10,6 +10,11 @@
|
||||
# Coverage: every menu string, tl! literal, plural, status and error message (enforced in tests).
|
||||
# Product, language, built-in workspace and perspective preset names follow MENU_KEEP_AS_IS.
|
||||
# Keep placeholders, ellipses and leading/trailing spaces of fragments when editing.
|
||||
Glowing Edges… Сяйливі краї…
|
||||
Glowing Edges Сяйливі краї
|
||||
Edge Width Ширина краю
|
||||
Edge Brightness Яскравість краю
|
||||
Smoothness Згладжування
|
||||
|
||||
Radial Blur… Радіальне розмиття…
|
||||
Smart Blur… Розумне розмиття…
|
||||
|
||||
|
@@ -9,6 +9,11 @@
|
||||
# proprietary localisation resource, string table or product UI may be copied. Product and
|
||||
# technology names stay in Latin letters. Full-width punctuation (,。:“”) in sentences, half-width
|
||||
# parentheses.
|
||||
Glowing Edges… 发光边缘…
|
||||
Glowing Edges 发光边缘
|
||||
Edge Width 边缘宽度
|
||||
Edge Brightness 边缘亮度
|
||||
Smoothness 平滑度
|
||||
|
||||
— missing — 缺失
|
||||
to search every command 以搜索所有命令
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -17,6 +17,11 @@
|
||||
# commands is kept. Full-width punctuation (,。:) inside sentences; half-width parentheses and
|
||||
# the " · " separators as in the English. Terms shared with PhotoCraft use the same words as its
|
||||
# zh-hant catalog (圖層, 選取, 偏好設定, 混合模式 ...), so the two apps read alike.
|
||||
Glowing Edges… 發光邊緣…
|
||||
Glowing Edges 發光邊緣
|
||||
Edge Width 邊緣寬度
|
||||
Edge Brightness 邊緣亮度
|
||||
Smoothness 平滑度
|
||||
|
||||
— missing — 遺失
|
||||
to search every command 以搜尋所有指令
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
Reference in new issue
Block a user