Merge pull request #3813 from Taha-Mahmoodi/feat/variable-font-filter

Font menu: Font Technology › Variable lists only variable font families
This commit is contained in:
BFlat
2026-10-24 02:44:40 +07:00
committed by GitHub
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