Font menu: Font Technology › Variable lists only variable font families

As Illustrator's help describes (Filter fonts by classification, Font Technology › Variable), the font menu gets a Font Technology row whose Variable choice lists only the families with variation axes, together with the script, kind, favourites and search filters, and stays set from one opening to the next. A family is variable when any of its faces, loaded or scanned, has an `fvar` table, so a family installed as static files beside a variable one counts.

Spec: https://helpx.adobe.com/illustrator/desktop/design-with-text/fonts-and-scripts/find-apply-and-adjust-variable-fonts.html
This commit is contained in:
Taha-Mahmoodi
2026-10-24 02:06:16 +07:00
committed by bflatastic
parent a26ac22794
commit 52d93cfce5
31 changed files with 263 additions and 33 deletions
+27 -9
View File
@@ -394,7 +394,7 @@ struct CatalogFamily {
/// Non-English family name from the name table, when the scan found one.
native: Option<String>,
faces: Vec<CatalogFace>,
/// The family's kind (from its first face found).
/// The family's kind (from its first face found); variable when any face found is.
traits: Option<FontTraits>,
}
@@ -754,17 +754,21 @@ impl FontClass {
[FontClass::Serif, FontClass::Sans, FontClass::Rounded, FontClass::Script, FontClass::Monospaced, FontClass::Decorative];
}
/// What a font menu filters on: whether a family sets Japanese or Thai, and its kind.
/// What a font menu filters on: whether a family sets Japanese or Thai, its kind, and whether it
/// is a variable font.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct FontTraits {
pub japanese: bool,
/// Its character map has Thai (ก and า).
pub thai: bool,
pub class: FontClass,
/// The face has variation axes (an `fvar` table of at most 64 axes); for a family, one of
/// its faces has.
pub variable: bool,
}
impl FontTraits {
/// From a face's OS/2 table (when it has one) and names.
/// From a face's OS/2 and `fvar` tables (when it has them) and names.
fn of(font: &skrifa::FontRef<'_>, keys: &FaceKeys) -> Self {
use skrifa::raw::TableProvider;
let os2 = font.os2().ok();
@@ -875,7 +879,8 @@ impl FontTraits {
} else {
FontClass::Other
};
FontTraits { japanese, thai, class }
let variable = (1..=MAX_AXES).contains(&font.axes().len());
FontTraits { japanese, thai, class, variable }
}
}
@@ -2007,7 +2012,8 @@ impl FontDb {
postscript.insert(ps.clone(), (family.clone(), style.clone()));
}
let entry = catalog.entry(family.to_ascii_lowercase()).or_default();
entry.traits.get_or_insert(traits);
let kind = entry.traits.get_or_insert(traits);
kind.variable |= traits.variable;
if entry.name.is_empty() {
entry.name = family;
}
@@ -2114,12 +2120,24 @@ impl FontDb {
}
/// The kind of `family` (whether it sets Japanese, its class), for font menu filters: from a
/// loaded face, else from the system font scan. Cheap: no font file is read.
/// loaded face, else from the system font scan. Variable when any of its faces, loaded or
/// scanned, is: a family may install static files beside a variable one. Cheap: no font file
/// is read, and a loaded family doesn't start the scan.
pub fn family_traits(&self, family: &str) -> FontTraits {
if let Some(f) = self.read_faces().iter().find(|f| f.family.eq_ignore_ascii_case(family)) {
return f.traits;
let loaded = {
let faces = self.read_faces();
let mut of_family = faces.iter().filter(|f| f.family.eq_ignore_ascii_case(family));
of_family.next().map(|first| FontTraits { variable: first.traits.variable || of_family.any(|f| f.traits.variable), ..first.traits })
};
let scanned = |catalog: &Catalog| catalog.get(&family.to_ascii_lowercase()).and_then(|c| c.traits);
match loaded {
None => scanned(&self.read_catalog()).unwrap_or_default(),
Some(traits) if traits.variable => traits,
Some(traits) => {
let variable = scanned(&self.catalog.read().unwrap_or_else(|e| e.into_inner())).is_some_and(|t| t.variable);
FontTraits { variable, ..traits }
}
}
self.read_catalog().get(&family.to_ascii_lowercase()).and_then(|c| c.traits).unwrap_or_default()
}
/// [`face`](Self::face) by any of the family's names ([`canonical`](Self::canonical)), and how
+12
View File
@@ -47,6 +47,18 @@ fn a_variable_font_lists_its_axes() {
assert!(db.face(FALLBACK_FAMILY, "Regular").unwrap().axes().is_empty(), "a static face");
}
/// Font menus' Font Technology › Variable: a family with variation axes is variable, the bundled
/// static families aren't.
#[test]
fn a_family_with_variation_axes_is_variable() {
let db = db();
assert!(db.family_traits(FAMILY).variable);
assert_eq!(db.family_traits(FAMILY).class, FontClass::Sans, "its kind is read as before");
for family in ["Source Sans 3", "Source Serif 4", "Inter", "JetBrains Mono"] {
assert!(!db.family_traits(family).variable, "{family} is static");
}
}
#[test]
fn axis_settings_lay_out_and_draw_between_the_named_instances() {
let db = db();
+31 -3
View File
@@ -15,10 +15,15 @@ fn renamed(file: &str) -> Vec<u8> {
/// A bundled Source Sans 3 file renamed `family`, which is as long as the original name.
fn renamed_to(file: &str, family: &str) -> Vec<u8> {
assert_eq!(family.len(), "Source Sans 3".len());
let mut data = std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("../../assets/fonts").join(file)).unwrap();
let data = std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("../../assets/fonts").join(file)).unwrap();
rename(data, "Source Sans 3", family)
}
/// The font `data` with family name `from` renamed `to`, which is as long.
fn rename(mut data: Vec<u8>, from: &str, to: &str) -> Vec<u8> {
assert_eq!(from.len(), to.len());
let utf16 = |s: &str| s.encode_utf16().flat_map(u16::to_be_bytes).collect::<Vec<u8>>();
for (from, to) in [(utf16("Source Sans 3"), utf16(family)), (b"Source Sans 3".to_vec(), family.as_bytes().to_vec())] {
for (from, to) in [(utf16(from), utf16(to)), (from.as_bytes().to_vec(), to.as_bytes().to_vec())] {
let mut i = 0;
while let Some(at) = data[i..].windows(from.len()).position(|w| w == from) {
data[i + at..i + at + to.len()].copy_from_slice(&to);
@@ -284,6 +289,29 @@ fn a_font_file_named_by_itself_is_scanned() {
assert_eq!(db.load_system_fonts(), 1);
}
/// Font menus' Font Technology › Variable: a family installed as static files beside a variable
/// one is variable, whether the scan reads a static file first or a static face is loaded.
#[test]
fn a_family_with_a_variable_file_beside_static_ones_is_variable() {
use crate::test_fonts::{VARIABLE_FAMILY, variable_font};
let dir = font_dir("variable");
assert!(!FontDb::with_font_dirs(vec![dir.clone()]).family_traits(FAMILY).variable, "static files only");
let var_dir = std::env::temp_dir().join(format!("vc-sysfonts-{}-variable-file", std::process::id()));
let _ = std::fs::remove_dir_all(&var_dir);
std::fs::create_dir_all(&var_dir).unwrap();
std::fs::write(var_dir.join("Sysfont-Variable.ttf"), rename(variable_font().unwrap(), VARIABLE_FAMILY, FAMILY)).unwrap();
// The folders are read last to first: the static files are found first.
let db = FontDb::with_font_dirs(vec![var_dir.clone(), dir]);
assert!(db.family_traits(FAMILY).variable);
assert!(!db.is_loaded(FAMILY), "the scan's traits, nothing loaded");
// A static face of the family loaded, its variable file only scanned.
let db = FontDb::with_font_dirs(vec![var_dir]);
assert!(db.has_family(FAMILY));
db.add_font(renamed("SourceSans3-Regular.ttf"));
assert!(db.is_loaded(FAMILY) && !db.face(FAMILY, "Regular").unwrap().traits.variable);
assert!(db.family_traits(FAMILY).variable);
}
#[test]
fn registered_fonts_outside_the_font_folders_are_their_full_paths() {
let dir = std::env::temp_dir().join("Fonts");
+127 -12
View File
@@ -4,10 +4,11 @@
//! or reached with ↑/↓ previews its font on the selected text (one live interaction, nothing in
//! the history); a click or Enter applies it as one step, Escape or closing the menu puts the text
//! back. The Glyphs panel and Find Font only pick a font ([`picked`]): nothing is previewed on the
//! document. A star marks a favourite family, and the ★ filter lists only those. Preferences ›
//! Type › Enable in-menu font previews and Font Preview Size turn the samples off or size the
//! rows. Recently used families appear first, in the order they were last applied, within the
//! same search and filters as the remaining families.
//! document. A star marks a favourite family, and the ★ filter lists only those. The Font
//! Technology filter's Variable lists only variable font families. Preferences › Type › Enable
//! in-menu font previews and Font Preview Size turn the samples off or size the rows. Recently
//! used families appear first, in the order they were last applied, within the same search and
//! filters as the remaining families.
use std::collections::HashMap;
use std::sync::Arc;
@@ -101,6 +102,12 @@ fn script_label(i: usize) -> &'static str {
}
}
/// The Font Technology filter's one choice: variable fonts. An adjective for fonts, not the
/// Variables panel's noun (`変数`), hence its context.
fn variable_label() -> &'static str {
crate::i18n::tr_ctx(crate::i18n::current(), "font-technology", "Variable")
}
/// Does a family of `traits` pass script filter `script` ([`SCRIPTS`])? Latin: neither Japanese
/// nor Thai.
fn script_matches(script: usize, traits: vectorcraft_text::FontTraits) -> bool {
@@ -193,9 +200,10 @@ fn remap_highlight(before: &[Row], selected: Option<usize>, after: &[Row]) -> Op
after.iter().position(|candidate| candidate == row)
}
/// What the rows were listed for: the query, the script, kind and favourites filters, Show Font
/// Names in English, the expanded families, favourites, recent history and font list generation.
type RowsKey = (String, usize, Option<FontClass>, bool, bool, Vec<String>, Vec<String>, Vec<String>, u64);
/// What the rows were listed for: the query, the script, kind, font technology (variable only) and
/// favourites filters, Show Font Names in English, the expanded families, favourites, recent
/// history and font list generation.
type RowsKey = (String, usize, Option<FontClass>, bool, bool, bool, Vec<String>, Vec<String>, Vec<String>, u64);
/// The menu's state between frames.
#[derive(Clone, Default)]
@@ -210,10 +218,11 @@ struct MenuState {
/// The highlighted row and the query and filters it belongs to.
highlight: Option<usize>,
query: String,
/// The filters (kept from one opening to the next): script (0..[`SCRIPTS`]), kind, and
/// favourites only.
/// The filters (kept from one opening to the next): script (0..[`SCRIPTS`]), kind, font
/// technology (variable fonts only) and favourites only.
script: usize,
class: Option<FontClass>,
variable_only: bool,
favorites_only: bool,
/// Families whose styles are listed (lowercase).
expanded: Vec<String>,
@@ -287,7 +296,7 @@ fn list(ui: &mut Ui, state_id: egui::Id, st: &mut MenuState, current: &str, samp
ui.memory_mut(|m| m.request_focus(field.with("edit")));
}
let query = widgets::search_field(ui, field, tl!("Search")).to_lowercase();
// The filters: script, then kind.
// The filters: script, then kind, then font technology.
let mut refilter = false;
ui.horizontal_wrapped(|ui| {
ui.spacing_mut().item_spacing = vec2(4.0, 2.0);
@@ -315,6 +324,14 @@ fn list(ui: &mut Ui, state_id: egui::Id, st: &mut MenuState, current: &str, samp
}
}
});
ui.horizontal_wrapped(|ui| {
ui.spacing_mut().item_spacing = vec2(4.0, 2.0);
ui.label(egui::RichText::new(tl!("Font Technology")).size(11.0).color(t.text_dim));
if ui.selectable_label(st.variable_only, egui::RichText::new(variable_label()).size(11.0)).clicked() {
st.variable_only = !st.variable_only;
refilter = true;
}
});
let enter = ui.input(|i| i.key_pressed(egui::Key::Enter));
let db = vectorcraft_text::FontDb::global();
// The current family by its own name (a document may name it in Japanese: ヒラギノ角ゴシック),
@@ -327,6 +344,7 @@ fn list(ui: &mut Ui, state_id: egui::Id, st: &mut MenuState, current: &str, samp
query.clone(),
st.script,
st.class,
st.variable_only,
st.favorites_only,
look.english_names,
st.expanded.clone(),
@@ -343,11 +361,11 @@ fn list(ui: &mut Ui, state_id: egui::Id, st: &mut MenuState, current: &str, samp
if st.favorites_only && !favorite(f) {
return false;
}
if st.script == 0 && st.class.is_none() {
if st.script == 0 && st.class.is_none() && !st.variable_only {
return true;
}
let traits = db.family_traits(f);
script_matches(st.script, traits) && st.class.is_none_or(|c| c == traits.class)
script_matches(st.script, traits) && st.class.is_none_or(|c| c == traits.class) && (!st.variable_only || traits.variable)
};
let families: Vec<_> = db.menu_family_list().iter().filter(|f| wanted(f)).cloned().collect();
let rows = grouped_rows(&families, look.recent, &st.expanded, |f| db.styles(f));
@@ -1059,4 +1077,101 @@ mod tests {
assert_eq!(remap_highlight(&before, Some(1), &after), Some(2));
assert_eq!(remap_highlight(&after, Some(1), &before), None);
}
/// The Font Technology filter's Variable is the font adjective, not the Variables panel's noun.
#[test]
fn the_variable_filter_is_named_as_fonts_are() {
use crate::i18n::{Lang, tr, tr_ctx};
let (ja, zh) = (Lang::from_code("ja").unwrap(), Lang::from_code("zh-hans").unwrap());
assert_eq!((tr_ctx(ja, "font-technology", "Variable"), tr(ja, "Variable")), ("バリアブル", "変数"));
assert_eq!((tr_ctx(zh, "font-technology", "Variable"), tr(zh, "Variable")), ("可变", "变量"));
assert_eq!(tr(ja, "Font Technology"), "フォントテクノロジー");
assert_eq!(super::variable_label(), "Variable");
}
/// Font Technology › Variable lists only variable font families, together with the other
/// filters; clicked again, every family is back.
#[test]
fn the_variable_filter_lists_only_variable_families() {
use vectorcraft_text::FontClass;
use vectorcraft_text::test_fonts::{TWO_AXIS_FAMILY, two_axis_font};
let db = vectorcraft_text::FontDb::global();
db.add_font(two_axis_font().unwrap());
let ctx = egui::Context::default();
let mut st = super::MenuState::default();
let mut favorites: Vec<String> = vec![];
let frame = |st: &mut super::MenuState, events, favorites: &[String]| {
let mut out = ctx.run_ui(
egui::RawInput {
events,
screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(600.0, 800.0))),
..Default::default()
},
|ui| {
super::list(
ui,
egui::Id::new("variable-filter"),
st,
"Source Sans 3",
None,
super::MenuLook { samples: false, favorites, ..Default::default() },
);
},
);
out.textures_delta.clear();
let button = out.shapes.iter().find_map(|c| match &c.shape {
egui::Shape::Text(t) if t.galley.text() == "Variable" => Some(t.visual_bounding_rect().center()),
_ => None,
});
let families: Vec<String> = st
.rows
.iter()
.filter_map(|r| match r {
Row::Family(f) => Some(f.clone()),
_ => None,
})
.collect();
(families, button)
};
let has = |list: &[String], f: &str| list.iter().any(|x| x == f);
let click = |st: &mut super::MenuState, favorites: &[String]| {
let (_, at) = frame(st, vec![], favorites);
let at = at.expect("the Variable filter is drawn");
let button =
|pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };
frame(st, vec![egui::Event::PointerMoved(at), button(true)], favorites);
frame(st, vec![button(false)], favorites);
frame(st, vec![], favorites).0
};
for _ in 0..3 {
frame(&mut st, vec![], &favorites);
}
let all = frame(&mut st, vec![], &favorites).0;
assert!(has(&all, TWO_AXIS_FAMILY) && has(&all, "Source Sans 3") && has(&all, "JetBrains Mono"), "{all:?}");
let variable = click(&mut st, &favorites);
assert!(st.variable_only, "the click turns the filter on");
assert!(has(&variable, TWO_AXIS_FAMILY), "{variable:?}");
assert!(!has(&variable, "Source Sans 3") && !has(&variable, "Inter") && !has(&variable, "JetBrains Mono"), "static families: {variable:?}");
assert!(variable.iter().all(|f| db.family_traits(f).variable), "{variable:?}");
// With the kind, script and favourites filters: each must pass.
st.class = Some(FontClass::Sans);
assert!(has(&frame(&mut st, vec![], &favorites).0, TWO_AXIS_FAMILY));
st.class = Some(FontClass::Monospaced);
assert!(!has(&frame(&mut st, vec![], &favorites).0, TWO_AXIS_FAMILY), "a sans serif family under Monospaced");
st.class = None;
st.script = 3;
assert!(!has(&frame(&mut st, vec![], &favorites).0, TWO_AXIS_FAMILY), "a family without Thai under Thai");
st.script = 0;
st.favorites_only = true;
favorites.push("Source Sans 3".into());
assert!(frame(&mut st, vec![], &favorites).0.is_empty(), "the one favourite is static");
favorites.push(TWO_AXIS_FAMILY.into());
assert_eq!(frame(&mut st, vec![], &favorites).0, [TWO_AXIS_FAMILY]);
st.favorites_only = false;
// Off again: every family is listed.
let again = click(&mut st, &favorites);
assert!(!st.variable_only);
assert_eq!(again, frame(&mut st, vec![], &[]).0);
assert!(has(&again, TWO_AXIS_FAMILY) && has(&again, "Source Sans 3") && has(&again, "JetBrains Mono"), "{again:?}");
}
}
+2
View File
@@ -180,6 +180,8 @@
Anti-aliased Artwork Загладено произведение
Anti-aliasing: Заглаждане:
Any Kind Всякакъв вид
Font Technology Технология на шрифта
font-technology Variable Променливи
Appearance Външен вид
Appearance Attribute Атрибут на външния вид
Appearance Item Елемент на външния вид
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -3818,6 +3818,8 @@ effect Regular Pravidelný
Put back in the dock Vrátit do doku
All Scripts Všechny systémy písma
Any Kind Libovolný druh
Font Technology Technologie písma
font-technology Variable Variabilní
Decorative Dekorativní
Favorites Oblíbené
Latin Latinka
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -3563,6 +3563,8 @@ effect Regular Regular
Put back in the dock Sæt tilbage i dokken
All Scripts Alle scripts
Any Kind Enhver type
Font Technology Skrifttypeteknologi
font-technology Variable Variable
Decorative Dekorative
Favorites Favoritter
Latin Latinsk
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -169,6 +169,8 @@
Anti-aliased Artwork Geglättete Grafik
Anti-aliasing: Glättung:
Any Kind Beliebige Art
Font Technology Schrifttechnologie
font-technology Variable Variabel
Appearance Aussehen
Appearance Attribute Aussehensattribut
Appearance Item Aussehenselement
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -174,6 +174,8 @@
Anti-aliased Artwork Γραφικά με εξομαλυμένες ακμές
Anti-aliasing: Εξομάλυνση ακμών:
Any Kind Οποιοσδήποτε τύπος
Font Technology Τεχνολογία γραμματοσειράς
font-technology Variable Μεταβλητές
Appearance Εμφάνιση
Appearance Attribute Χαρακτηριστικό εμφάνισης
Appearance Item Στοιχείο εμφάνισης
1 # Ελληνικά (el) — VectorCraft
174
175
176
177 font-technology
178
179
180
181
+2
View File
@@ -194,6 +194,8 @@
Anti-aliased Artwork Ilustración suavizada
Anti-aliasing: Suavizado:
Any Kind Cualquier tipo
Font Technology Tecnología de fuente
font-technology Variable Variables
Appearance Apariencia
Appearance Attribute Atributo de apariencia
Appearance Item Elemento de apariencia
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -3742,6 +3742,8 @@ effect Regular Normaali
Put back in the dock Palauta telakkaan
All Scripts Kaikki kirjoitusjärjestelmät
Any Kind Mikä tahansa laji
Font Technology Fonttitekniikka
font-technology Variable Muuttuvat
Decorative Koristeelliset
Favorites Suosikit
Latin Latinalainen
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -195,6 +195,8 @@
Anti-aliased Artwork Illustration lissée
Anti-aliasing: Lissage :
Any Kind Tout type
Font Technology Technologie de police
font-technology Variable Variables
Appearance Aspect
Appearance Attribute Attribut d’aspect
Appearance Item Élément d’aspect
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -277,6 +277,8 @@
Anti-aliasing: Élsimítás:
Any except extracting pages Bármi, kivéve az oldalak kinyerését
Any Kind Bármilyen típus
Font Technology Betűtípus-technológia
font-technology Variable Változó
Appearance Megjelenés
Appearance Attribute Megjelenési attribútum
Appearance Item Megjelenési elem
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -3563,6 +3563,8 @@ effect Regular Reguler
Put back in the dock Kembalikan ke dok
All Scripts Semua skrip
Any Kind Jenis apa pun
Font Technology Teknologi font
font-technology Variable Variabel
Decorative Dekoratif
Favorites Favorit
Latin Latin
1 # Indonesian (id) catalog. Same format as zh-hant.tsv: context <TAB> source <TAB> translation
3563
3564
3565 font-technology
3566
3567
3568
3569
3570
+2
View File
@@ -194,6 +194,8 @@
Anti-aliased Artwork Grafica con anti-aliasing
Anti-aliasing: Anti-aliasing:
Any Kind Qualsiasi tipo
Font Technology Tecnologia font
font-technology Variable Variabili
Appearance Aspetto
Appearance Attribute Attributo aspetto
Appearance Item Elemento aspetto
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -18,6 +18,8 @@
All Scripts すべての文字
Anchors: アンカー:
Any Kind すべての種類
Font Technology フォントテクノロジー
font-technology Variable バリアブル
Ascender アセンダ
Baseline ベースライン
Bottom-to-Bottom Leading 欧文ベースライン基準の行送り
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -3346,6 +3346,8 @@ effect Regular ჩვეულებრივი
Put back in the dock დოკში დაბრუნება
All Scripts ყველა დამწერლობა
Any Kind ნებისმიერი ტიპი
Font Technology შრიფტის ტექნოლოგია
font-technology Variable ცვლადი
Decorative დეკორატიული
Favorites რჩეულები
Latin ლათინური
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -14,6 +14,8 @@
All Scripts 모든 스크립트
Anchors: 앵커:
Any Kind 모든 종류
Font Technology 글꼴 기술
font-technology Variable 가변
Ascender 어센더
Baseline 기준선
Bottom-to-Bottom Leading 아래쪽 기준 행간
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -3577,6 +3577,8 @@ effect Regular Regelmatig
Put back in the dock Terugzetten in het dock
All Scripts Alle scripts
Any Kind Elke soort
Font Technology Lettertypetechnologie
font-technology Variable Variabel
Decorative Decoratief
Favorites Favorieten
Latin Latijns
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -3657,6 +3657,8 @@ effect Regular Normalny
Put back in the dock Odłóż z powrotem do doku
All Scripts Wszystkie skrypty
Any Kind Dowolny rodzaj
Font Technology Technologia czcionek
font-technology Variable Zmienne
Decorative Ozdobne
Favorites Ulubione
Latin Łacińskie
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -3107,6 +3107,8 @@ lighting Light Luz
All Scripts Todos os scripts
Anchors: Âncoras:
Any Kind Qualquer tipo
Font Technology Tecnologia da Fonte
font-technology Variable Variáveis
Apply Aplicar
Ellipse Properties: Propriedades da elipse:
Invert Pie Inverter fatia
Can't render this file because it contains an unexpected character in line 6 and column 47.
+2
View File
@@ -192,6 +192,8 @@
Anti-aliased Artwork Сглаженный рисунок
Anti-aliasing: Сглаживание:
Any Kind Любой тип
Font Technology Технология шрифта
font-technology Variable Вариативные
Appearance Оформление
Appearance Attribute Атрибут оформления
Appearance Item Элемент оформления
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -182,6 +182,8 @@
Anti-aliased Artwork Kantutjämnad grafik
Anti-aliasing: Kantutjämning:
Any Kind Alla typer
Font Technology Teckensnittsteknik
font-technology Variable Variabla
Appearance Utseende
Appearance Attribute Utseendeattribut
Appearance Item Utseendeobjekt
Can't render this file because it contains an unexpected character in line 5 and column 25.
+2
View File
@@ -179,6 +179,8 @@
Anti-aliased Artwork Kenar Yumuşatılmış Sanat Çalışması
Anti-aliasing: Kenar yumuşatma:
Any Kind Her Türlü
Font Technology Yazı Tipi Teknolojisi
font-technology Variable Değişken
Appearance Görünüm
Appearance Attribute Görünüm Özniteliği
Appearance Item Görünüm Öğesi
Can't render this file because it contains an unexpected character in line 5 and column 25.
+2
View File
@@ -188,6 +188,8 @@
Anti-aliased Artwork Згладжений малюнок
Anti-aliasing: Згладжування:
Any Kind Будь-який тип
Font Technology Технологія шрифту
font-technology Variable Варіативні
Appearance Оформлення
Appearance Attribute Атрибут оформлення
Appearance Item Елемент оформлення
1 # Ukrainian (uk) catalog. Same format as zh-hant.tsv: context <TAB> source <TAB> translation.
188
189
190 font-technology
191
192
193
194
195
+2
View File
@@ -212,6 +212,8 @@
Anti-aliased Artwork Tác phẩm khử răng cưa
Anti-aliasing: Khử răng cưa:
Any Kind Bất kỳ loại
Font Technology Công nghệ phông chữ
font-technology Variable Biến thiên
Appearance Diện mạo
Appearance Attribute Thuộc tính diện mạo
Appearance Item Mục diện mạo
1 # Vietnamese (vi) catalog. Same format as zh-hant.tsv: context <TAB> source <TAB> translation
212
213
214
215
216 font-technology
217
218
219
+2
View File
@@ -4609,6 +4609,8 @@ imageTrace Outline 轮廓
# The Layers panel, the graphics processor preference and the font menu's filters.
All Scripts 所有文字系统
Any Kind 所有类型
Font Technology 字体技术
font-technology Variable 可变
Applies the next time VectorCraft starts. 下次启动 VectorCraft 时生效。
Collapse to Icons 折叠为图标
Decorative 装饰
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -152,6 +152,8 @@
Anti-aliased Artwork 消除鋸齒的圖稿
Anti-aliasing: 消除鋸齒:
Any Kind 所有類型
Font Technology 字體技術
font-technology Variable 可變
Appearance 外觀
Appearance Attribute 外觀屬性
Appearance Item 外觀項目
Can't render this file because it contains an unexpected character in line 6 and column 47.
+8 -2
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3 -2
View File
File diff suppressed because one or more lines are too long