mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 23:05:05 +00:00
Glyphs: Entire Font applies a glyph no feature reaches to the selected letter as a glyph choice; text tests for ligatures, word probe, candidate cap and aalt order
This commit is contained in:
@@ -58,7 +58,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Glyphs",
|
||||
[],
|
||||
None,
|
||||
"{id, start: byte (a character of it), gid: glyph id|null} draw that one character with another glyph of its font as one undo step, what a double-click in the Glyphs panel's Show › Alternates for Current Selection does: gid is one of the glyphs text.glyphAlternates lists for it; its own default glyph, or null, puts the default glyph back. The text keeps the character, and its other attributes do not change. The choice is saved with the character's style and names the face it was made in (PostScript name and version): set in another font or version, or after the font goes missing, the character takes its default glyph; typed characters take their default glyphs. Choosing the glyph the character already draws is not an edit. An error when the character's font is not available, the glyph is not one of its alternates, or the character's style does not draw it (All Caps, Small Caps, another numeral system) → {id, start, end (the character's bytes), gid (the glyph drawn)}",
|
||||
"{id, start: byte (a character of it), gid: glyph id|null} draw that one character with another glyph of its font as one undo step, what a double-click in the Glyphs panel's Show › Alternates for Current Selection does: gid is one of the glyphs text.glyphAlternates lists for it, a glyph no character maps and no feature reaches whose name is not another letter's (`a.salt` for a), its own default glyph, or null, puts the default glyph back. The text keeps the character, and its other attributes do not change. The choice is saved with the character's style and names the face it was made in (PostScript name and version): set in another font or version, or after the font goes missing, the character takes its default glyph; typed characters take their default glyphs. Choosing the glyph the character already draws is not an edit. An error when the character's font is not available, the glyph is not one of those, or the character's style does not draw it (All Caps, Small Caps, another numeral system) → {id, start, end (the character's bytes), gid (the glyph drawn)}",
|
||||
has_doc,
|
||||
set_glyph_alternate
|
||||
),
|
||||
@@ -1294,7 +1294,7 @@ fn set_glyph_alternate(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let substituted = unchosen.is_some_and(|g| g != default);
|
||||
let choice = match gid.filter(|g| *g != default || substituted) {
|
||||
None => None,
|
||||
Some(g) if g == default || face.alternates(ch).iter().any(|a| a.gid == g) => Some(face.choice(ch, g)),
|
||||
Some(g) if g == default || face.alternates(ch).iter().any(|a| a.gid == g) || face.is_unlisted_alternate(ch, g) => Some(face.choice(ch, g)),
|
||||
Some(g) => return Err(bad(C, format!("glyph {g} is not an alternate of {ch} in {} {}", face.family, face.style))),
|
||||
};
|
||||
let drawn = choice.as_ref().map_or(unchosen.unwrap_or(default), |c| c.gid);
|
||||
|
||||
@@ -67,6 +67,38 @@ impl FontFace {
|
||||
.clone()
|
||||
}
|
||||
|
||||
/// Is glyph `gid` one no character maps and no feature reaches, whose name does not give it
|
||||
/// to another letter than `c` (`a.salt` for `a` in a font with no `salt`; `A.salt` is not
|
||||
/// `a`'s)? Such a glyph is not among [`Self::alternates`], yet it can be drawn for `c` as a
|
||||
/// glyph choice ([`Self::choice`]).
|
||||
pub fn is_unlisted_alternate(&self, c: char, gid: u32) -> bool {
|
||||
self.unencoded_glyphs().binary_search(&gid).is_ok()
|
||||
&& self.feature_reaching(gid).is_none()
|
||||
&& self.glyph_origin(gid).is_none()
|
||||
&& self.name_owner(gid).is_none_or(|owner| owner == c)
|
||||
}
|
||||
|
||||
/// The character a glyph's name says it belongs to: the one whose glyph carries the name up
|
||||
/// to its first `.` (`A` for `A.salt`, `s` for `s.ss1`; the lowest character when several map
|
||||
/// that glyph). `None` when the glyph has no name, or no character maps a glyph of that name.
|
||||
fn name_owner(&self, gid: u32) -> Option<char> {
|
||||
let base = self.glyph_name(gid)?;
|
||||
let base = base.split('.').next().unwrap_or_default();
|
||||
let names = self.named_chars.get_or_init(|| {
|
||||
let Some(font) = self.skrifa() else { return Default::default() };
|
||||
let mut by_char: Vec<(char, u32)> = font.charmap().mappings().filter_map(|(c, g)| Some((char::from_u32(c)?, g.to_u32()))).collect();
|
||||
by_char.sort_unstable();
|
||||
let mut out = std::collections::HashMap::new();
|
||||
for (c, g) in by_char {
|
||||
if let Some(name) = self.glyph_name(g) {
|
||||
out.entry(name).or_insert(c);
|
||||
}
|
||||
}
|
||||
out
|
||||
});
|
||||
names.get(base).copied()
|
||||
}
|
||||
|
||||
/// How many glyphs the face has (its `maxp` table; 0 when it can't be read).
|
||||
pub fn glyph_count(&self) -> u32 {
|
||||
self.skrifa().and_then(|f| f.maxp().ok()).map_or(0, |m| u32::from(m.num_glyphs()))
|
||||
|
||||
@@ -80,6 +80,7 @@ pub(super) fn make_face(bytes: FontBytes, index: u32, spec: FaceStyle, path: Opt
|
||||
svg_glyphs,
|
||||
gsub: std::sync::OnceLock::new(),
|
||||
unencoded: std::sync::OnceLock::new(),
|
||||
named_chars: std::sync::OnceLock::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -204,6 +204,8 @@ pub struct FontFace {
|
||||
pub(super) gsub: std::sync::OnceLock<super::gsub::GsubIndex>,
|
||||
/// [`Self::unencoded_glyphs`], read once.
|
||||
pub(super) unencoded: std::sync::OnceLock<std::sync::Arc<[u32]>>,
|
||||
/// [`Self::name_owner`]'s glyph names to characters, read once.
|
||||
pub(super) named_chars: std::sync::OnceLock<std::collections::HashMap<String, char>>,
|
||||
}
|
||||
|
||||
/// Where the ideographic character face (ICF) lies inside the ideographic em box: its distance
|
||||
|
||||
@@ -735,6 +735,49 @@ pub fn alternates_font(aalt: bool) -> Option<Vec<u8>> {
|
||||
Some(builder.build())
|
||||
}
|
||||
|
||||
/// The family of [`capped_candidates_font`].
|
||||
pub const CAPPED_CANDIDATES_FAMILY: &str = "Captest Sans";
|
||||
|
||||
/// The bundled Source Sans 3 Regular, its `cmap` kept, with a `GSUB` table for `a` of an `aalt`
|
||||
/// alternate substitution that lists `b` 512 times (the longest set read: 512 values to try) and a
|
||||
/// `salt` single substitution that gives `c`. Family [`CAPPED_CANDIDATES_FAMILY`]. `None` when it
|
||||
/// can't be built.
|
||||
pub fn capped_candidates_font() -> Option<Vec<u8>> {
|
||||
use write_fonts::tables::gsub::{
|
||||
AlternateSet, AlternateSubstFormat1, Gsub, SingleSubst, SingleSubstFormat2, SubstitutionLookup, SubstitutionLookupList,
|
||||
};
|
||||
use write_fonts::tables::layout::{CoverageFormat1, Feature, FeatureList, FeatureRecord, LangSys, Lookup, Script, ScriptList, ScriptRecord};
|
||||
use write_fonts::types::GlyphId16;
|
||||
|
||||
const BASE: &[u8] = include_bytes!("../../../assets/fonts/SourceSans3-Regular.ttf");
|
||||
let font = skrifa::FontRef::new(BASE).ok()?;
|
||||
let charmap = font.charmap();
|
||||
let name =
|
||||
name_table(&[(1, CAPPED_CANDIDATES_FAMILY), (2, "Regular"), (4, "Captest Sans Regular"), (5, "Version 1.000"), (6, "CaptestSans-Regular")])?;
|
||||
let mut builder = FontBuilder::new();
|
||||
builder.add_raw(Tag::new(b"name"), name);
|
||||
let gid = |c| Some(GlyphId16::new(u16::try_from(charmap.map(c)?.to_u32()).ok()?));
|
||||
let a = gid('a')?;
|
||||
let cover = || CoverageFormat1::new(vec![a]);
|
||||
let alternates = AlternateSubstFormat1::new(cover().into(), vec![AlternateSet::new(vec![gid('b')?; 512])]);
|
||||
let salt = SingleSubst::from(SingleSubstFormat2::new(cover().into(), vec![gid('c')?]));
|
||||
let lookups = SubstitutionLookupList::new(vec![
|
||||
SubstitutionLookup::Alternate(Lookup::new(Default::default(), vec![alternates])),
|
||||
SubstitutionLookup::Single(Lookup::new(Default::default(), vec![salt])),
|
||||
]);
|
||||
let records =
|
||||
vec![FeatureRecord::new(Tag::new(b"aalt"), Feature::new(None, vec![0])), FeatureRecord::new(Tag::new(b"salt"), Feature::new(None, vec![1]))];
|
||||
let scripts = ScriptList::new(vec![ScriptRecord::new(Tag::new(b"DFLT"), Script::new(Some(LangSys::new(vec![0, 1])), vec![]))]);
|
||||
builder.add_table(&Gsub::new(scripts, FeatureList::new(records), lookups)).ok()?;
|
||||
for r in font.table_directory.table_records() {
|
||||
let tag = Tag::new(&r.tag().to_be_bytes());
|
||||
if !builder.contains(tag) {
|
||||
builder.add_raw(tag, font.table_data(r.tag())?.as_bytes());
|
||||
}
|
||||
}
|
||||
Some(builder.build())
|
||||
}
|
||||
|
||||
/// The family of [`joining_alternates_font`].
|
||||
pub const JOINING_ALTERNATES_FAMILY: &str = "Jointest Sans";
|
||||
|
||||
|
||||
@@ -346,6 +346,100 @@ fn a_variant_no_feature_draws_has_no_feature_to_apply() {
|
||||
assert!(face.unencoded_glyphs().contains(&u1) && !face.unencoded_glyphs().contains(&face.glyph_for('a')));
|
||||
}
|
||||
|
||||
/// The alternates are listed `aalt` first, then `salt`, the stylistic sets, `swsh` and `cv01`, each
|
||||
/// glyph once under the first feature that lists it, whichever feature draws it in the text.
|
||||
#[test]
|
||||
fn alternates_are_listed_aalt_first_under_the_first_feature_that_lists_them() {
|
||||
use crate::test_fonts::{alternates_family, alternates_font, unencoded_glyphs};
|
||||
let db = FontDb::with_font_dirs(vec![]);
|
||||
db.add_font(alternates_font(true).expect("the test font builds"));
|
||||
let [u1, u2, u3, u4] = unencoded_glyphs().expect("unencoded glyphs");
|
||||
let face = db.face(alternates_family(true), "Regular").expect("the test face");
|
||||
let st = CharStyle { font_family: alternates_family(true).into(), size: 100.0, ..CharStyle::default() };
|
||||
let found = alternates_in_context(&db, &TextObject::point(Point::ZERO, "xay", st), 1).expect("the a");
|
||||
let listed: Vec<(u32, [u8; 4], Option<String>)> = found.alternates.iter().map(|a| (a.gid, a.feature, a.apply.clone())).collect();
|
||||
let (a, b, c) = (face.glyph_for('a'), face.glyph_for('b'), face.glyph_for('c'));
|
||||
assert_eq!(
|
||||
listed,
|
||||
[
|
||||
(a, *b"aalt", Some("aalt".to_string())),
|
||||
(u1, *b"aalt", Some("swsh=2".to_string())),
|
||||
(b, *b"aalt", Some("salt".to_string())),
|
||||
(u2, *b"ss01", Some("ss01".to_string())),
|
||||
(u4, *b"ss02", Some("ss02".to_string())),
|
||||
(u3, *b"swsh", Some("swsh".to_string())),
|
||||
(c, *b"cv01", None),
|
||||
],
|
||||
"aalt's set first, with the default glyph it lists; b is aalt's though salt draws it"
|
||||
);
|
||||
}
|
||||
|
||||
/// A glyph that more than its character makes (the lam-alef ligature) has no alternates of its own
|
||||
/// there, though the font substitutes it (`salt`).
|
||||
#[test]
|
||||
fn a_ligature_has_no_alternates_in_context() {
|
||||
use crate::test_fonts::{LAM_ALEF_SALT, lam_alef_family, lam_alef_font};
|
||||
let db = FontDb::with_font_dirs(vec![]);
|
||||
db.add_font(lam_alef_font(b"rlig").expect("the test font builds"));
|
||||
let family = lam_alef_family(b"rlig");
|
||||
let face = db.face(family, "Regular").expect("the test face");
|
||||
let lam_alef = TextObject::point(Point::ZERO, "\u{0644}\u{0627}", style(family, &[]));
|
||||
let ligature = g('H');
|
||||
assert_eq!(
|
||||
face.substitutions(ligature).iter().map(|s| s.glyphs.clone()).collect::<Vec<_>>(),
|
||||
[vec![g(LAM_ALEF_SALT)]],
|
||||
"the font gives the ligature an alternate"
|
||||
);
|
||||
let found = alternates_in_context(&db, &lam_alef, 0).expect("the ligature");
|
||||
assert_eq!((found.default, found.current), (ligature, ligature));
|
||||
assert!(found.alternates.is_empty(), "{:?}", found.alternates);
|
||||
// The lam alone is its own character: it has no alternates because the font gives it none.
|
||||
let alone = alternates_in_context(&db, &TextObject::point(Point::ZERO, "\u{0644}", style(family, &[])), 0).expect("the lam");
|
||||
assert_eq!(alone.default, g('l'));
|
||||
}
|
||||
|
||||
/// A word is shaped as one piece (to 256 characters each side of the selected one), the selected
|
||||
/// character found in it by its offset: a letter deep in a long word and the letters next to a
|
||||
/// space, a line feed or a line separator each get the form their place in their own word gives.
|
||||
#[test]
|
||||
fn the_probe_finds_the_character_in_its_word_across_a_long_word_and_breaks() {
|
||||
let db = db();
|
||||
let text = |s: &str| TextObject::point(Point::ZERO, s, style(JOINING_ALTERNATES_FAMILY, &[]));
|
||||
let default_of = |t: &TextObject, byte: usize| {
|
||||
let found = alternates_in_context(&db, t, byte).expect("a character");
|
||||
(found.default, found.alternates.len())
|
||||
};
|
||||
// 700 letters: beh, 698 teh, noon. Each is found at its own offset, 300 of them past the
|
||||
// 256 characters either side that are shaped.
|
||||
let long = text(&format!("{BEH}{}{NOON}", TEH.repeat(698)));
|
||||
assert_eq!(default_of(&long, 0), (g('B'), 0), "the first letter is initial");
|
||||
assert_eq!(default_of(&long, 2 * 300), (g('u'), 3), "a medial teh deep in the word, with its alternates");
|
||||
assert_eq!(default_of(&long, 2 * 699), (g('M'), 0), "the last letter is final");
|
||||
// Two words: the break leaves each its own initial and final letters. The teh before the break
|
||||
// ends its word (final) and the one after starts the next (initial), not medial.
|
||||
for brk in [" ", "\n", "\u{2028}", "\u{2029}"] {
|
||||
let two = text(&format!("{BEH}{TEH}{brk}{TEH}{NOON}"));
|
||||
let after = 2 * 2 + brk.len();
|
||||
assert_eq!(default_of(&two, 2), (g('U'), 2), "{brk:?}: final teh before the break, with its two alternates");
|
||||
assert_eq!(default_of(&two, after), (g('T'), 0), "{brk:?}: initial teh after it");
|
||||
assert_eq!(default_of(&two, after + 2), (g('M'), 0), "{brk:?}: the noon after it is final");
|
||||
}
|
||||
}
|
||||
|
||||
/// A word of alternates longer than the candidates tried (512) leaves the features after it
|
||||
/// untried: `aalt`'s 512 values use them all, so `salt`'s glyph is listed but no feature is applied
|
||||
/// for it.
|
||||
#[test]
|
||||
fn the_candidates_tried_are_capped() {
|
||||
use crate::test_fonts::{CAPPED_CANDIDATES_FAMILY, capped_candidates_font};
|
||||
let db = FontDb::with_font_dirs(vec![]);
|
||||
db.add_font(capped_candidates_font().expect("the test font builds"));
|
||||
let face = db.face(CAPPED_CANDIDATES_FAMILY, "Regular").expect("the test face");
|
||||
let found = alternates_in_context(&db, &TextObject::point(Point::ZERO, "xay", style(CAPPED_CANDIDATES_FAMILY, &[])), 1).expect("the a");
|
||||
let listed: Vec<(u32, Option<String>)> = found.alternates.iter().map(|a| (a.gid, a.apply.clone())).collect();
|
||||
assert_eq!(listed, [(face.glyph_for('b'), Some("aalt".to_string())), (face.glyph_for('c'), None)]);
|
||||
}
|
||||
|
||||
/// A feature on a one-byte character (Latin) reaches that character: the range of a feature is
|
||||
/// its source bytes, and harfrust applies a range `a..b` to clusters `a..b - 1` unless the end is
|
||||
/// inclusive, which would leave a one-byte character out.
|
||||
|
||||
@@ -854,7 +854,6 @@ font-technology Variable Променливи
|
||||
at the end of a word в края на дума
|
||||
standing alone когато стои сам
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} не е алтернатива на {sel} (U+{code}) там, където е в думата си.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Никоя OpenType функция не извежда {glyph}, затова не може да се приложи към текст.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Двойно щракване за вмъкване на {base} (U+{code}): представителната форма не се свързва, буквата се свързва.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Вмъкнато е {base} (U+{code}) вместо представителна форма: шрифтът я свързва със съседите според позицията.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Нито една OpenType функция не рисува този глиф тук, затова той заменя глифа на знака и може да не се свързва със съседните знаци.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1562,7 +1562,6 @@ digits Malayalam Malajalam
|
||||
at the end of a word na kraju riječi
|
||||
standing alone kad stoji sam
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} nije alternativa znaku {sel} (U+{code}) onako kako stoji u svojoj riječi.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Nijedna OpenType funkcija ne daje {glyph}, pa se ne može primijeniti na tekst.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Dvostruki klik za umetanje znaka {base} (U+{code}): oblik za prikaz se ne spaja, slovo se spaja.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Umetnut je znak {base} (U+{code}) umjesto oblika za prikaz: font ga spaja sa susjedima prema položaju.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Nijedna OpenType funkcija ne crta ovaj glif ovdje, pa on zamjenjuje glif znaka i možda se neće spajati sa susjednim znakovima.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1216,7 +1216,6 @@
|
||||
at the end of a word al final d’una paraula
|
||||
standing alone quan va sol
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} no és una alternativa de {sel} (U+{code}) tal com es troba a la seva paraula.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Cap funció OpenType arriba a {glyph}, de manera que no es pot aplicar al text.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Feu doble clic per inserir {base} (U+{code}): una forma de presentació no s’uneix, la lletra sí.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. S’ha inserit {base} (U+{code}) en lloc d’una forma de presentació: el tipus de lletra l’uneix als veïns segons la posició.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Cap funció OpenType dibuixa aquest glif aquí, de manera que substitueix el glif del caràcter i pot no unir-se als caràcters veïns.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1586,7 +1586,6 @@ digits Malayalam Malajálamské
|
||||
at the end of a word na konci slova
|
||||
standing alone když stojí samostatně
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} není alternativou znaku {sel} (U+{code}) tak, jak stojí ve svém slově.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Žádná funkce OpenType nedává {glyph}, proto ho nelze použít na text.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Dvojklikem vložíte {base} (U+{code}): prezentační tvar se nespojuje, písmeno ano.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Vloženo {base} (U+{code}) místo prezentačního tvaru: písmo ho podle polohy spojí se sousedy.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Žádná funkce OpenType tento glyf zde nekreslí, proto nahradí glyf znaku a nemusí se spojit se sousedními znaky.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1496,7 +1496,6 @@ digits Malayalam Malayalam
|
||||
at the end of a word i slutningen af et ord
|
||||
standing alone når det står alene
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} er ikke et alternativ til {sel} (U+{code}), som det står i sit ord.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Ingen OpenType-funktion giver {glyph}, så det kan ikke anvendes på tekst.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Dobbeltklik for at indsætte {base} (U+{code}) i stedet: en præsentationsform forbindes ikke, bogstavet gør.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. {base} (U+{code}) er indsat i stedet for en præsentationsform: skrifttypen forbinder det med naboerne efter position.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Ingen OpenType-funktion tegner dette glyf her, så det erstatter tegnets glyf og forbindes måske ikke med nabotegnene.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -848,7 +848,6 @@ font-technology Variable Variabel
|
||||
at the end of a word am Wortende
|
||||
standing alone allein stehend
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} ist keine Alternative zu {sel} (U+{code}), so wie es in seinem Wort steht.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Keine OpenType-Funktion liefert {glyph}, daher lässt es sich nicht auf Text anwenden.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Doppelklicken, um stattdessen {base} (U+{code}) einzufügen: Eine Darstellungsform verbindet sich nicht, der Buchstabe schon.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. {base} (U+{code}) statt einer Darstellungsform eingefügt: Die Schrift verbindet es je nach Position mit den Nachbarn.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Keine OpenType-Funktion zeichnet diese Glyphe hier, daher ersetzt sie die Glyphe des Zeichens und verbindet sich möglicherweise nicht mit den Nachbarzeichen.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -827,7 +827,6 @@ font-technology Variable Μεταβλητές
|
||||
at the end of a word στο τέλος μιας λέξης
|
||||
standing alone όταν στέκεται μόνος
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. Ο γλύφος {glyph} δεν είναι εναλλακτικός του {sel} (U+{code}) όπως βρίσκεται στη λέξη του.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Καμία λειτουργία OpenType δεν δίνει τον γλύφο {glyph}, οπότε δεν μπορεί να εφαρμοστεί στο κείμενο.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Διπλό κλικ για εισαγωγή του {base} (U+{code}): μια μορφή παρουσίασης δεν συνδέεται, το γράμμα συνδέεται.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Εισήχθη το {base} (U+{code}) αντί για μορφή παρουσίασης: η γραμματοσειρά το συνδέει με τους γείτονες ανάλογα με τη θέση.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Καμία λειτουργία OpenType δεν σχεδιάζει αυτόν τον γλύφο εδώ, οπότε αντικαθιστά τον γλύφο του χαρακτήρα και μπορεί να μην συνδέεται με τους γειτονικούς χαρακτήρες.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 163 and column 5.
|
@@ -869,7 +869,6 @@ font-technology Variable Variables
|
||||
at the end of a word al final de una palabra
|
||||
standing alone cuando está solo
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} no es una alternativa de {sel} (U+{code}) tal como está en su palabra.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Ninguna función OpenType llega a {glyph}, así que no se puede aplicar al texto.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Doble clic para insertar {base} (U+{code}) en su lugar: una forma de presentación no se une, la letra sí.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Se insertó {base} (U+{code}) en lugar de una forma de presentación: la fuente la une a sus vecinas según la posición.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Ninguna función OpenType dibuja este glifo aquí, así que sustituye el glifo del carácter y puede que no se una a los caracteres vecinos.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1559,7 +1559,6 @@ digits Malayalam Malajalam
|
||||
at the end of a word sanan lopussa
|
||||
standing alone yksinään
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} ei ole merkin {sel} (U+{code}) vaihtoehto sellaisena kuin se on sanassaan.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Mikään OpenType-ominaisuus ei tuota glyfiä {glyph}, joten sitä ei voi käyttää tekstiin.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Lisää kaksoisnapsauttamalla sen sijaan {base} (U+{code}): esitysmuoto ei liity, kirjain liittyy.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Lisättiin {base} (U+{code}) esitysmuodon sijaan: fontti liittää sen naapureihin sijainnin mukaan.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Mikään OpenType-ominaisuus ei piirrä tätä glyfiä tässä, joten se korvaa merkin glyfin eikä välttämättä liity viereisiin merkkeihin.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -872,7 +872,6 @@ font-technology Variable Variables
|
||||
at the end of a word à la fin d’un mot
|
||||
standing alone isolé
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} n’est pas une variante de {sel} (U+{code}) tel qu’il se trouve dans son mot.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Aucune fonction OpenType n’atteint {glyph} ; il ne peut donc pas être appliqué au texte.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Double-cliquez pour insérer {base} (U+{code}) à la place : une forme de présentation ne se lie pas, la lettre si.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. {base} (U+{code}) a été inséré à la place d’une forme de présentation : la police le lie à ses voisins selon la position.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Aucune fonction OpenType ne dessine ce glyphe ici : il remplace le glyphe du caractère et peut ne pas se lier aux caractères voisins.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1352,7 +1352,6 @@
|
||||
at the end of a word शब्द के अंत में
|
||||
standing alone अकेले खड़े होने पर
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph}, {sel} (U+{code}) का विकल्प नहीं है, जैसा वह अपने शब्द में खड़ा है।
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. कोई OpenType फ़ीचर {glyph} तक नहीं पहुँचता, इसलिए इसे टेक्स्ट पर लागू नहीं किया जा सकता।
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. इसके बजाय {base} (U+{code}) सम्मिलित करने के लिए डबल क्लिक करें: प्रेज़ेंटेशन फ़ॉर्म नहीं जुड़ता, अक्षर जुड़ता है।
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. प्रेज़ेंटेशन फ़ॉर्म की जगह {base} (U+{code}) सम्मिलित किया गया: फ़ॉन्ट उसे स्थिति के अनुसार पड़ोसियों से जोड़ता है।
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. यहाँ कोई OpenType फ़ीचर इस ग्लिफ़ को नहीं बनाता, इसलिए यह कैरेक्टर के ग्लिफ़ की जगह लेता है और पड़ोसी कैरेक्टरों से जुड़ नहीं भी सकता।
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -1122,7 +1122,6 @@ font-technology Variable Változó
|
||||
at the end of a word szó végén
|
||||
standing alone önállóan állva
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. A(z) {glyph} nem változata a(z) {sel} (U+{code}) karakternek úgy, ahogy a szavában áll.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Egyetlen OpenType-funkció sem éri el a(z) {glyph} glifát, ezért nem alkalmazható a szövegre.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Dupla kattintással ezt szúrod be helyette: {base} (U+{code}); a megjelenítési forma nem kapcsolódik, a betű igen.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. A megjelenítési forma helyett ez lett beszúrva: {base} (U+{code}); a betűtípus pozíció szerint kapcsolja a szomszédokhoz.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Itt egyetlen OpenType-funkció sem rajzolja meg ezt a glifát, ezért a karakter glifáját váltja fel, és előfordulhat, hogy nem kapcsolódik a szomszédos karakterekhez.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1496,7 +1496,6 @@ digits Malayalam Malayalam
|
||||
at the end of a word di akhir kata
|
||||
standing alone saat berdiri sendiri
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} bukan alternatif {sel} (U+{code}) sebagaimana posisinya di dalam katanya.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Tidak ada fitur OpenType yang menghasilkan {glyph}, jadi tidak bisa diterapkan ke teks.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Klik ganda untuk menyisipkan {base} (U+{code}) sebagai gantinya: bentuk presentasi tidak menyambung, hurufnya menyambung.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. {base} (U+{code}) disisipkan sebagai ganti bentuk presentasi: font menyambungkannya ke huruf di sebelahnya menurut posisi.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Tidak ada fitur OpenType yang menggambar glif ini di sini, jadi glif ini menggantikan glif karakter dan mungkin tidak menyambung dengan karakter di sebelahnya.
|
||||
|
||||
|
@@ -869,7 +869,6 @@ font-technology Variable Variabili
|
||||
at the end of a word alla fine di una parola
|
||||
standing alone da solo
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} non è un’alternativa di {sel} (U+{code}) così come si trova nella sua parola.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Nessuna funzione OpenType raggiunge {glyph}, quindi non può essere applicato al testo.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Fai doppio clic per inserire invece {base} (U+{code}): una forma di presentazione non si unisce, la lettera sì.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Inserito {base} (U+{code}) al posto di una forma di presentazione: il font lo unisce ai vicini in base alla posizione.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Nessuna funzione OpenType disegna questo glifo qui: sostituisce il glifo del carattere e potrebbe non unirsi ai caratteri vicini.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1432,7 +1432,6 @@ digits Malayalam マラヤーラム数字
|
||||
at the end of a word 語末
|
||||
standing alone 単独のとき
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} は、{sel} (U+{code}) が単語の中で置かれている位置での異体字ではありません。
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. {glyph} に到達する OpenType フィーチャーはないため、テキストに適用できません。
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. ダブルクリックで代わりに {base} (U+{code}) を挿入: 表示形は前後とつながりませんが、文字はつながります。
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. 表示形の代わりに {base} (U+{code}) を挿入しました。フォントが位置に応じて前後の文字とつなげます。
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. このグリフを表示する OpenType フィーチャーがないため、文字のグリフが置き換わり、前後の文字とつながらないことがあります。
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1422,7 +1422,6 @@ digits Malayalam მალაიალამური
|
||||
at the end of a word სიტყვის ბოლოს
|
||||
standing alone როცა ცალკე დგას
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} არ არის {sel} (U+{code})-ის ალტერნატივა იმ სახით, როგორც ის თავის სიტყვაშია.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. არც ერთი OpenType ფუნქცია არ იძლევა {glyph}-ს, ამიტომ მისი ტექსტზე გამოყენება შეუძლებელია.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. ორჯერ დაწკაპეთ ამის ნაცვლად {base} (U+{code}) ჩასასმელად: გამოსახვის ფორმა არ უკავშირდება, ასო უკავშირდება.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. გამოსახვის ფორმის ნაცვლად ჩასმულია {base} (U+{code}): შრიფტი მას მეზობლებს პოზიციის მიხედვით აკავშირებს.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. აქ არც ერთი OpenType ფუნქცია არ ხატავს ამ გლიფს, ამიტომ ის ანაცვლებს სიმბოლოს გლიფს და შეიძლება არ დაუკავშირდეს მეზობელ სიმბოლოებს.
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -1422,7 +1422,6 @@ digits Malayalam 말라얄람어
|
||||
at the end of a word 단어 끝
|
||||
standing alone 단독일 때
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph}은(는) 단어 안에 있는 {sel}(U+{code})의 대체 글리프가 아닙니다.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. {glyph}에 도달하는 OpenType 기능이 없으므로 텍스트에 적용할 수 없습니다.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. 더블클릭하여 대신 {base}(U+{code}) 삽입: 표시 형태는 연결되지 않지만 글자는 연결됩니다.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. 표시 형태 대신 {base}(U+{code})을(를) 삽입했습니다. 글꼴이 위치에 따라 이웃 문자와 연결합니다.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. 이 글리프를 그리는 OpenType 기능이 없으므로 문자의 글리프를 대체하며 이웃 문자와 연결되지 않을 수 있습니다.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1510,7 +1510,6 @@ digits Malayalam Malayalam
|
||||
at the end of a word aan het einde van een woord
|
||||
standing alone los staand
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} is geen alternatief voor {sel} (U+{code}) zoals het in zijn woord staat.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Geen enkele OpenType-functie levert {glyph}, dus het kan niet op tekst worden toegepast.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Dubbelklik om in plaats daarvan {base} (U+{code}) in te voegen: een presentatievorm sluit niet aan, de letter wel.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. {base} (U+{code}) ingevoegd in plaats van een presentatievorm: het lettertype verbindt het naar positie met de buren.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Geen enkele OpenType-functie tekent deze glyph hier, dus hij vervangt de glyph van het teken en sluit mogelijk niet aan op de buurtekens.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1499,7 +1499,6 @@ digits Malayalam Malajalam
|
||||
at the end of a word na końcu wyrazu
|
||||
standing alone gdy stoi osobno
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} nie jest alternatywą znaku {sel} (U+{code}) w takiej postaci, w jakiej stoi w swoim wyrazie.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Żadna funkcja OpenType nie daje glifu {glyph}, więc nie można go zastosować do tekstu.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Kliknij dwukrotnie, aby wstawić zamiast tego {base} (U+{code}): forma prezentacyjna się nie łączy, litera tak.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Wstawiono {base} (U+{code}) zamiast formy prezentacyjnej: czcionka łączy go z sąsiadami zależnie od pozycji.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Żadna funkcja OpenType nie rysuje tutaj tego glifu, więc zastępuje on glif znaku i może nie łączyć się z sąsiednimi znakami.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -779,7 +779,6 @@
|
||||
at the end of a word no fim de uma palavra
|
||||
standing alone quando está sozinho
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} não é uma alternativa de {sel} (U+{code}) como ele está em sua palavra.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Nenhum recurso OpenType chega a {glyph}, então ele não pode ser aplicado ao texto.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Clique duplo para inserir {base} (U+{code}) no lugar: uma forma de apresentação não se une, a letra sim.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. {base} (U+{code}) foi inserido no lugar de uma forma de apresentação: a fonte o une aos vizinhos conforme a posição.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Nenhum recurso OpenType desenha este glifo aqui, então ele substitui o glifo do caractere e pode não se unir aos caracteres vizinhos.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -867,7 +867,6 @@ font-technology Variable Вариативные
|
||||
at the end of a word в конце слова
|
||||
standing alone в отдельном виде
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} не является альтернативой символа {sel} (U+{code}) в том виде, как он стоит в своём слове.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Ни одна функция OpenType не даёт {glyph}, поэтому его нельзя применить к тексту.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Дважды щёлкните, чтобы вставить вместо него {base} (U+{code}): форма представления не соединяется, буква соединяется.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Вместо формы представления вставлено {base} (U+{code}): шрифт соединяет его с соседними по положению.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Ни одна функция OpenType не рисует здесь этот глиф, поэтому он заменяет глиф символа и может не соединяться с соседними символами.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -856,7 +856,6 @@ font-technology Variable Variabla
|
||||
at the end of a word i slutet av ett ord
|
||||
standing alone när det står ensamt
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} är inget alternativ till {sel} (U+{code}) som det står i sitt ord.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Ingen OpenType-funktion ger {glyph}, så den kan inte användas på text.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Dubbelklicka för att infoga {base} (U+{code}) i stället: en presentationsform ansluter inte, bokstaven gör det.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. {base} (U+{code}) infogades i stället för en presentationsform: typsnittet ansluter det till grannarna efter position.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Ingen OpenType-funktion ritar den här glyfen här, så den ersätter tecknets glyf och ansluter kanske inte till grannteckenen.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -848,7 +848,6 @@ font-technology Variable Değişken
|
||||
at the end of a word kelimenin sonunda
|
||||
standing alone tek başına dururken
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph}, kendi kelimesinde durduğu hâliyle {sel} (U+{code}) karakterinin alternatifi değil.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Hiçbir OpenType özelliği {glyph} glifine ulaşmaz; bu yüzden metne uygulanamaz.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Bunun yerine {base} (U+{code}) eklemek için çift tıklayın: sunum biçimi bağlanmaz, harf bağlanır.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Sunum biçimi yerine {base} (U+{code}) eklendi: yazı tipi onu konumuna göre komşularına bağlar.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Hiçbir OpenType özelliği bu glifi burada çizmez; bu yüzden karakterin glifinin yerine geçer ve komşu karakterlere bağlanmayabilir.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -863,7 +863,6 @@ font-technology Variable Варіативні
|
||||
at the end of a word наприкінці слова
|
||||
standing alone в окремому вигляді
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} не є альтернативою символу {sel} (U+{code}) у тому вигляді, в якому він стоїть у своєму слові.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Жодна функція OpenType не дає {glyph}, тому його не можна застосувати до тексту.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Двічі клацніть, щоб вставити замість нього {base} (U+{code}): форма подання не з’єднується, літера з’єднується.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Замість форми подання вставлено {base} (U+{code}): шрифт з’єднує його із сусідніми за положенням.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Жодна функція OpenType не малює тут цей гліф, тому він замінює гліф символу й може не з’єднуватися із сусідніми символами.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 177 and column 5.
|
@@ -1007,7 +1007,6 @@ font-technology Variable Biến thiên
|
||||
at the end of a word ở cuối từ
|
||||
standing alone khi đứng riêng
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} không phải glyph thay thế của {sel} (U+{code}) như ký tự đó đang đứng trong từ của nó.
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. Không có tính năng OpenType nào đạt tới {glyph}, nên không thể áp dụng cho văn bản.
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. Bấm đúp để chèn {base} (U+{code}) thay thế: dạng trình bày không nối, còn chữ cái thì nối.
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. Đã chèn {base} (U+{code}) thay cho dạng trình bày: phông chữ nối nó với các ký tự bên cạnh theo vị trí.
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. Không có tính năng OpenType nào vẽ glyph này ở đây, nên nó thay glyph của ký tự và có thể không nối với các ký tự bên cạnh.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 199 and column 5.
|
@@ -811,7 +811,6 @@
|
||||
at the end of a word 位于词尾
|
||||
standing alone 单独出现时
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} 不是 {sel}(U+{code})在其单词中所处位置的替代字。
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. 没有任何 OpenType 功能能得到 {glyph},因此无法应用于文本。
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. 双击以改为插入 {base}(U+{code}):表现形式不会连接,字母会连接。
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. 已插入 {base}(U+{code})以代替表现形式:字体会按位置将其与相邻字符连接。
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. 没有任何 OpenType 功能会在此处绘制该字形,因此它会替换该字符的字形,并且可能无法与相邻字符连接。
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -831,7 +831,6 @@ font-technology Variable 可變
|
||||
at the end of a word 位於詞尾
|
||||
standing alone 單獨出現時
|
||||
{glyph} is not an alternate of {sel} (U+{code}) as it stands in its word. {glyph} 不是 {sel}(U+{code})在其單字中所處位置的替代字。
|
||||
No OpenType feature reaches {glyph}, so it cannot be applied to text. 沒有任何 OpenType 功能能得到 {glyph},因此無法套用到文字。
|
||||
Double-click to insert {base} (U+{code}) instead: a presentation form does not join, the letter does. 按兩下以改為插入 {base}(U+{code}):表現形式不會連接,字母會連接。
|
||||
Inserted {base} (U+{code}) instead of a presentation form: the font joins it to its neighbors by position. 已插入 {base}(U+{code})以取代表現形式:字體會依位置將其與相鄰字元連接。
|
||||
No OpenType feature draws this glyph here, so it replaces the character's glyph and may not join its neighbors. 沒有任何 OpenType 功能會在此處繪製該字形,因此它會取代該字元的字形,且可能無法與相鄰字元連接。
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -292,7 +292,7 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
ui.painter().rect_stroke(rect.shrink(0.5), 0, edge, StrokeKind::Inside);
|
||||
// A glyph no character maps is dimmed when it cannot go on the selection.
|
||||
let pick = match (c, &fit) {
|
||||
(None, Some(fit)) => Some(fit.pick(gid)),
|
||||
(None, Some(fit)) => Some(fit.pick(&face, gid)),
|
||||
_ => None,
|
||||
};
|
||||
let ink = if matches!(pick, Some(None)) { t.text_disabled } else { t.text_strong };
|
||||
@@ -585,20 +585,24 @@ impl Fit {
|
||||
|
||||
/// What a double-click on glyph `gid` does to the selected character: the way to draw it with
|
||||
/// that glyph, when it is the character's default glyph or one of its alternates as it stands
|
||||
/// in its word, in the face the selected text is set in. `None` when it is not.
|
||||
fn pick(&self, gid: u32) -> Option<Pick> {
|
||||
/// in its word, in the face the selected text is set in; or a glyph no feature reaches that
|
||||
/// the font's naming does not give to another letter (`A.salt` for `A`, `s.ss1` in a font
|
||||
/// with no `ss01`), which is drawn as a glyph choice. `None` when it is not.
|
||||
fn pick(&self, face: &vectorcraft_text::FontFace, gid: u32) -> Option<Pick> {
|
||||
let t = self.target.as_ref().filter(|t| t.available)?;
|
||||
let found = t.found.as_ref().filter(|f| f.font_id == self.face_id)?;
|
||||
if gid == found.default {
|
||||
return Some(Pick::Default);
|
||||
}
|
||||
let a = found.alternates.iter().find(|a| a.gid == gid)?;
|
||||
Some(a.apply.clone().map_or(Pick::Glyph(gid), Pick::Feature))
|
||||
if let Some(a) = found.alternates.iter().find(|a| a.gid == gid) {
|
||||
return Some(a.apply.clone().map_or(Pick::Glyph(gid), Pick::Feature));
|
||||
}
|
||||
face.is_unlisted_alternate(t.ch, gid).then_some(Pick::Glyph(gid))
|
||||
}
|
||||
|
||||
/// Why [`Self::pick`] finds nothing for glyph `gid` of `face`, in the user's words: what the
|
||||
/// glyph belongs to (its letter and place in a word, from the font's own substitutions) and what
|
||||
/// the selection is, that no feature reaches it, or that nothing is selected.
|
||||
/// the selection is, or that nothing is selected.
|
||||
fn why(&self, face: &vectorcraft_text::FontFace, gid: u32) -> String {
|
||||
let Some(t) = &self.target else { return tl!("Select one character with the Type tool first.").to_string() };
|
||||
if !t.available {
|
||||
@@ -619,12 +623,7 @@ impl Fit {
|
||||
&[("glyph", &name), ("sel", &sel), ("code", &sel_code)],
|
||||
)
|
||||
};
|
||||
let Some(origin) = face.glyph_origin(gid) else {
|
||||
return match face.feature_reaching(gid) {
|
||||
Some(_) => not_alternate(),
|
||||
None => crate::i18n::fmt(tl!("No OpenType feature reaches {glyph}, so it cannot be applied to text."), &[("glyph", &name)]),
|
||||
};
|
||||
};
|
||||
let Some(origin) = face.glyph_origin(gid) else { return not_alternate() };
|
||||
let place = match origin.position() {
|
||||
Some(vectorcraft_text::JoiningPosition::Initial) => Some(tl!("at the start of a word")),
|
||||
Some(vectorcraft_text::JoiningPosition::Medial) => Some(tl!("in the middle of a word")),
|
||||
@@ -1303,7 +1302,7 @@ mod tests {
|
||||
let raw = egui::RawInput { screen_rect: Some(Rect::from_min_size(Pos2::ZERO, TALL)), ..Default::default() };
|
||||
let mut frame = ctx.run_ui(raw, |ui| {
|
||||
let fit = Fit::of(app, ui, face);
|
||||
out = fit.pick(gid).ok_or_else(|| fit.why(face, gid));
|
||||
out = fit.pick(face, gid).ok_or_else(|| fit.why(face, gid));
|
||||
});
|
||||
frame.textures_delta.clear();
|
||||
out
|
||||
@@ -1422,7 +1421,7 @@ mod tests {
|
||||
assert_eq!(ink, Tokens::get(&ctx).text_strong);
|
||||
double_click_in(&ctx, &mut app, at, TALL);
|
||||
assert_eq!(glyph_ids(&app, &id).last(), Some(&glyph));
|
||||
// Nothing selected, a glyph no feature reaches, and a variant of the letter's other form.
|
||||
// Nothing selected, and a variant of the letter's other form.
|
||||
select(&mut app, 0, 0);
|
||||
assert_eq!(verdict(&ctx, &app, &face, glyph).err().as_deref(), Some("Select one character with the Type tool first."));
|
||||
let (_, ink) = entire_font_cell(&ctx, &mut app, &face, glyph);
|
||||
@@ -1434,11 +1433,50 @@ mod tests {
|
||||
Some("yehfarsi.medi.alt1 is not an alternate of ی (U+06CC) as it stands in its word."),
|
||||
"its own letter, another place in a word"
|
||||
);
|
||||
let unreached = face.unencoded_glyphs().iter().copied().find(|g| face.glyph_origin(*g).is_none() && face.feature_reaching(*g).is_none());
|
||||
if let Some(g) = unreached {
|
||||
let why = verdict(&ctx, &app, &face, g).err().expect("not applicable");
|
||||
assert!(why.starts_with("No OpenType feature reaches "), "{why}");
|
||||
}
|
||||
|
||||
/// A glyph no feature reaches (`a.a`, `a.b` of a font with no feature for them) is applied by
|
||||
/// Entire Font to the selected character as a glyph choice, not dimmed; one the font's naming
|
||||
/// gives to another letter (`a.a` on `y`) stays dimmed, and so does every glyph with no
|
||||
/// character selected.
|
||||
#[test]
|
||||
fn entire_font_applies_a_glyph_no_feature_reaches_to_its_letter() {
|
||||
use vectorcraft_text::test_fonts::{alternates_family, alternates_font};
|
||||
FontDb::global().add_font(alternates_font(true).expect("the test font builds"));
|
||||
let face = FontDb::global().face(alternates_family(true), "Regular").expect("the test face");
|
||||
let glyph = gid_named(&face, "a.a");
|
||||
assert!(face.feature_reaching(glyph).is_none() && face.glyph_origin(glyph).is_none(), "no feature reaches it");
|
||||
let (mut app, id) = editing("xay");
|
||||
app.run("text.setRangeStyle", json!({"id": id, "font": alternates_family(true)})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
let t = Tokens::get(&ctx);
|
||||
let plain = glyph_ids(&app, &id);
|
||||
// The cell of the glyph and its colour: this font's grid is longer than the panel is tall,
|
||||
// but the glyph is in the first rows.
|
||||
let cell_of = |ctx: &egui::Context, app: &mut VectorcraftApp| {
|
||||
let chars = face.chars().into_iter().filter(|(c, _)| !c.is_control() && !c.is_whitespace()).count();
|
||||
let at = chars + face.unencoded_glyphs().iter().position(|g| *g == glyph).expect("an unencoded glyph");
|
||||
let cells = inks(&tall_shapes(ctx, app));
|
||||
(cells[at].0.center(), cells[at].1)
|
||||
};
|
||||
// Another letter, and nothing selected: dimmed, and a double-click changes nothing.
|
||||
for (start, end) in [(2, 3), (0, 0)] {
|
||||
select(&mut app, start, end);
|
||||
assert!(verdict(&ctx, &app, &face, glyph).is_err());
|
||||
let (at, ink) = cell_of(&ctx, &mut app);
|
||||
assert_eq!(ink, t.text_disabled, "{start}..{end}: dimmed");
|
||||
double_click_in(&ctx, &mut app, at, TALL);
|
||||
assert_eq!(glyph_ids(&app, &id), plain);
|
||||
}
|
||||
// The letter itself: enabled, one undo step, drawn with that glyph.
|
||||
select(&mut app, 1, 2);
|
||||
assert!(matches!(verdict(&ctx, &app, &face, glyph), Ok(Pick::Glyph(g)) if g == glyph));
|
||||
let (at, ink) = cell_of(&ctx, &mut app);
|
||||
assert_eq!(ink, t.text_strong);
|
||||
let undo = app.session.active().unwrap().history.undo.len();
|
||||
double_click_in(&ctx, &mut app, at, TALL);
|
||||
assert_eq!(app.session.active().unwrap().history.undo.len(), undo + 1);
|
||||
assert_eq!(glyph_ids(&app, &id), [plain[0], glyph, plain[2]]);
|
||||
}
|
||||
|
||||
/// A presentation form picked in Entire Font (beh medial, U+FE92) with the caret before the last
|
||||
|
||||
+1
-1
@@ -372,7 +372,7 @@ from G14 and the budget run of G15: **~170–270 h** one agent, ~50–80 h wall
|
||||
|
||||
## G4 Advanced type
|
||||
|
||||
- **Done (#5514):** the Glyphs panel's Alternates for Current Selection lists the alternates of the glyph the shaper makes for the selected character in its word, and a double-click applies the OpenType feature value that draws one (`salt=2`, `ss03`) to that character alone, in one undo step, so the text stays real Unicode and an Arabic word keeps its joining forms: runs that differ only in their features are shaped as one piece of text. A variant no feature draws there is still drawn as a replacement glyph, which may not join. Show › Entire Font lists the unencoded glyphs by id, with their name and the feature that gives them; a double-click on one applies it to the selected character when the font gives it as that character's alternate in its word (`yehfarsi.fina.alt2` on a final Persian yeh), and any other is drawn dimmed with a tooltip that says why (it belongs to another letter or place in a word, no feature reaches it, nothing is selected). An Arabic presentation form picked there inserts its letter, so the word still joins. Left: alternates reached through contextual or ligature lookups, and `cv01`–`cv99` and `hist`, which have no style tag; estimate unchanged.
|
||||
- **Done (#5514):** the Glyphs panel's Alternates for Current Selection lists the alternates of the glyph the shaper makes for the selected character in its word, and a double-click applies the OpenType feature value that draws one (`salt=2`, `ss03`) to that character alone, in one undo step, so the text stays real Unicode and an Arabic word keeps its joining forms: runs that differ only in their features are shaped as one piece of text. A variant no feature draws there is still drawn as a replacement glyph, which may not join. Show › Entire Font lists the unencoded glyphs by id, with their name and the feature that gives them; a double-click on one applies it to the selected character when the font gives it as that character's alternate in its word (`yehfarsi.fina.alt2` on a final Persian yeh), and a glyph no feature reaches whose name does not belong to another letter (`A.salt`, `s.ss1` in a font with no such feature) is applied to the selected character as a glyph choice, which may not join; any other is drawn dimmed with a tooltip that says why (it belongs to another letter or place in a word, nothing is selected). An Arabic presentation form picked there inserts its letter, so the word still joins. Left: alternates reached through contextual or ligature lookups, and `cv01`–`cv99` and `hist`, which have no style tag; estimate unchanged.
|
||||
|
||||
- **Fixed:** fullwidth `!` / `?` stay upright in vertical point and area type when a font has no vertical alternate. Existing `vert` substitutions and the rotated fallback for brackets and long vowel marks are preserved; the broader CJK gap and estimate are unchanged.
|
||||
|
||||
|
||||
+4
-3
@@ -5735,13 +5735,14 @@ drawn now, and `alternates` the glyphs the font's `GSUB` single and alternate su
|
||||
glyph: `aalt` first, then `salt`, `ss01` to `ss20`, `swsh`, `cv01` to `cv99`, `hist`, `jalt`, `nalt`, `ornm` and
|
||||
`titl`, in lookup order within each, each glyph once. The default glyph is listed only when `aalt` lists it. Ligatures
|
||||
and contextual substitutions are not listed. `text.setGlyphAlternate {id, start, gid}` draws the character with glyph
|
||||
`gid`, one of those alternates or the default glyph, as one undo step; `gid: null` takes the choice away, and the
|
||||
`gid`, one of those alternates, a glyph that no character maps and no feature reaches whose name is not another letter's
|
||||
(`a.salt` for `a`, in a font with no `salt`), or the default glyph, as one undo step; `gid: null` takes the choice away, and the
|
||||
character is drawn as its style draws it (a feature such as `salt` can draw another glyph than the default). The text
|
||||
keeps the character and its other attributes, and characters typed next to it take their default glyphs. The choice is
|
||||
saved with the character's style as `glyphAlternate: {ch, gid, font, version}`, the face's PostScript name and version
|
||||
string: set in another font or version, or with the font missing, the character takes its default glyph. Both commands
|
||||
refuse a character whose font is not available, and `text.setGlyphAlternate` refuses a glyph that is not one of the
|
||||
character's alternates and a glyph that the character's style does not draw (All Caps, Small Caps or another numeral
|
||||
refuse a character whose font is not available, and `text.setGlyphAlternate` refuses a glyph that is not one of those
|
||||
and a glyph that the character's style does not draw (All Caps, Small Caps or another numeral
|
||||
system). Choosing the glyph a character already draws is not an edit. Character styles do not take `glyphAlternate`:
|
||||
`charStyle.new`, `charStyle.edit` and `charStyle.setAttrs` refuse it.
|
||||
|
||||
|
||||
+2
-2
@@ -31,7 +31,7 @@ against Illustrator's public documentation; **estimated** unless noted.
|
||||
| Character size and horizontal scale after object/group scaling | done | #1034: fields and setters compensate the stored affine; point size follows the transformed em-height axis, not the glyph ink bounds. Range edits, keyboard increments, leading and baseline shift use document points; rotation, reflection and shear remain editable. |
|
||||
| Preserve font sizes while scaling a group | missing | Separate enhancement; scaling still scales text with the other artwork. |
|
||||
| OpenType panel, Glyphs panel, alternates | done | Highlight Alternate Glyphs preference (#394, off by default) paints pink behind OpenType substitutions on screen when on (required shaping such as Arabic joining forms and the lam-alef ligature, including a lam-alef older fonts file under `liga`, is not highlighted; an optional feature that changes the ligature is); stylistic sets ss01–ss20, stylistic and titling alternates, proportional and lining figures, superscript and subscript are character-style features (`text.setStyle {features}`, #1607); the OpenType panel's Position menu sets superscript, subscript, numerator or denominator glyphs (`sups`, `subs`, `numr`, `dnom`). The OpenType panel's Stylistic Sets menu lists the selected font's `ss01`–`ss20` features, using a font-supplied name where available and `Set N` otherwise; several sets can be active, and selecting an active one removes it. For a mixed-font selection it uses the first selected character's font, a VectorCraft design choice ([public help](https://helpx.adobe.com/illustrator/desktop/design-with-text/special-characters-glyphs/add-stylistic-sets-to-selected-text.html), [OpenType feature specification](https://learn.microsoft.com/en-us/typography/opentype/spec/features_pt)). The Glyphs panel highlights the character selected with the Type tool (a range's first character, else the one before the caret) and scrolls it into view as the selection moves (#4908; `panels::glyphs` tests); its Show menu lists Unicode ranges and Alternates for Current Selection, the selected character's alternate glyphs from the font's `GSUB` table, a double-click applies the OpenType feature that draws one (`salt=N`, `ssNN`) to that character alone; a variant no feature reaches is drawn through `text.setGlyphAlternate`, which may not join; Show › Entire Font applies the selected letter's alternates the same way and dims the others with the reason; the glyph-cell pop-up of alternates is not there yet |
|
||||
| Glyphs panel: alternates as OpenType feature values, unencoded glyphs | done | #5514, as [Replace characters with alternate glyphs](https://helpx.adobe.com/illustrator/desktop/design-with-text/special-characters-glyphs/replace-characters-with-alternate-glyphs.html) describes (Show › Alternates For Current Selection; replace the selected character by double-clicking the glyph). A character-style feature takes a value (`"salt=2"`, the font's alternate number; `ss01`–`ss20`, `swsh`, `titl` and `aalt` too) in `features` and `featureChanges`, in SVG `font-feature-settings` (`"salt" 2`) and in native files as the plain string. Show › Entire Font applies an unencoded glyph the same way when it is an alternate of the selected character in its word, and dims the others with the reason in the tooltip (e.g. `yehfarsi.fina.alt2 belongs to ی (U+06CC) at the end of a word; your selection is ي (U+064A)`); an Arabic presentation form picked there inserts its letter so the word joins. Runs that differ only in their features shape as one piece of text, each run's features over its own characters, so a variant on one letter of an Arabic word keeps its neighbours' initial, medial and final forms and the letters still touch. The panel lists the alternates of the glyph the shaper makes for the selected character in its word (a medial letter shows medial variants), and a double-click applies the OpenType feature that draws the variant (`salt=N` or `ssNN`) to that character alone, in one undo step (`text.setRangeStyle`); a variant no feature reaches falls back to a replacement glyph (`text.setGlyphAlternate`), which its tooltip says may not join. Show › Entire Font also lists the glyphs no character maps, with their name or `gid N` and the feature that gives them. The text crate reads each face's `GSUB` once (alternate sets, single substitutions, the feature that reaches a glyph). Not done: alternates reached through contextual or ligature lookups, and features of the font that the style has no tag for (`cv01`–`cv99`, `hist`). Evidence: `tests::glyph_alternates` in the text crate (a fixture font with a medial teh at `salt=1` to `3`, the neighbours' forms, no gap; Kufi Murabba PIIIX when it is installed), `features::tests::feature_values_are_parsed_validated_and_shaped`, `tests::textedit::feature_values_are_set_replaced_and_saved`, the `panels::glyphs` tests. |
|
||||
| Glyphs panel: alternates as OpenType feature values, unencoded glyphs | done | #5514, as [Replace characters with alternate glyphs](https://helpx.adobe.com/illustrator/desktop/design-with-text/special-characters-glyphs/replace-characters-with-alternate-glyphs.html) describes (Show › Alternates For Current Selection; replace the selected character by double-clicking the glyph). A character-style feature takes a value (`"salt=2"`, the font's alternate number; `ss01`–`ss20`, `swsh`, `titl` and `aalt` too) in `features` and `featureChanges`, in SVG `font-feature-settings` (`"salt" 2`) and in native files as the plain string. Show › Entire Font applies an unencoded glyph the same way when it is an alternate of the selected character in its word, applies one no feature reaches (`A.salt` in a font with no `salt`) to the selected character as a glyph choice (it may not join), and dims the others with the reason in the tooltip (e.g. `yehfarsi.fina.alt2 belongs to ی (U+06CC) at the end of a word; your selection is ي (U+064A)`); an Arabic presentation form picked there inserts its letter so the word joins. Runs that differ only in their features shape as one piece of text, each run's features over its own characters, so a variant on one letter of an Arabic word keeps its neighbours' initial, medial and final forms and the letters still touch. The panel lists the alternates of the glyph the shaper makes for the selected character in its word (a medial letter shows medial variants), and a double-click applies the OpenType feature that draws the variant (`salt=N` or `ssNN`) to that character alone, in one undo step (`text.setRangeStyle`); a variant no feature reaches falls back to a replacement glyph (`text.setGlyphAlternate`), which its tooltip says may not join. Show › Entire Font also lists the glyphs no character maps, with their name or `gid N` and the feature that gives them. The text crate reads each face's `GSUB` once (alternate sets, single substitutions, the feature that reaches a glyph). Not done: alternates reached through contextual or ligature lookups, and features of the font that the style has no tag for (`cv01`–`cv99`, `hist`). Evidence: `tests::glyph_alternates` in the text crate (a fixture font with a medial teh at `salt=1` to `3`, the neighbours' forms, no gap; Kufi Murabba PIIIX when it is installed), `features::tests::feature_values_are_parsed_validated_and_shaped`, `tests::textedit::feature_values_are_set_replaced_and_saved`, the `panels::glyphs` tests. |
|
||||
| Font menu: samples, live preview, filters, favourites, recent families; font matching by any name; Find Font | done | #3515: recently applied families appear first, once each; missing families are omitted and the existing Number of Recent Fonts setting applies; #339; script filter: Japanese, Latin, Thai; the font scan on Linux also reads the folders fontconfig's configuration lists, such as TeX fonts under `/usr/share/texmf/fonts` (#1548, fixes #1529; not verified on Linux) Replace With Font lists family and style rows, one click setting both, with a search over them; its list scrolls on its own, apart from the document's font list (#4972). |
|
||||
| Missing glyphs set in an installed font made for their script (Thai, Lao, Khmer, Myanmar first; then any font that has them) | done | Thai: Leelawadee UI, Tahoma, Thonburi, Sukhumvit Set, Noto Sans Thai, TLWG |
|
||||
| Full font-name matching (OpenType name ID 4) | done | #1258: loaded/cataloged faces and Missing Fonts searches; localized names and variable default faces; Windows font-service QA pending |
|
||||
@@ -80,7 +80,7 @@ Character Styles menu New/Redefine and footer New capture the first selected cha
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-07 | minor | Glyphs panel (#5514): Alternates for Current Selection lists the alternates of the selected character's glyph in its word and a double-click applies the OpenType feature that draws one to that letter alone (`salt=2`; `features` and `featureChanges` take `tag=N`), so an Arabic word stays joined, and Entire Font lists the unencoded glyphs, applies the ones that are the selected letter's alternates and dims, with the reason, those that are not. Runs that differ only in their features shape as one piece of text. Scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | Glyphs panel (#5514): Alternates for Current Selection lists the alternates of the selected character's glyph in its word and a double-click applies the OpenType feature that draws one to that letter alone (`salt=2`; `features` and `featureChanges` take `tag=N`), so an Arabic word stays joined, and Entire Font lists the unencoded glyphs, applies the ones that are the selected letter's alternates, or that no feature reaches and the font's names do not give to another letter, and dims, with the reason, those that are not. Runs that differ only in their features shape as one piece of text. Scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | Indian-language hyphenation (#4947): eleven MIT-licensed pattern sets, with grapheme and shaping-cluster protection in both composers and existing paragraph limits. Assamese and Sanskrit are selectable; Sanskrit automatic patterns remain pending an allowlisted source. Scores and estimates unchanged. |
|
||||
| 2026-11-06 | minor | Alt + numeric-keypad codes (`Alt+0176` → °) type their character at the caret on Windows, and `type.insert` inserts a character by `code` or `unicode` (#5108); scores and estimates unchanged |
|
||||
| 2026-11-06 | minor | Snap to Glyph › Glyph Bounds: each glyph's box gives four corners a drawn point lands on, also on a curved side (`B`), and its box and edges turn with rotated type (#5112); scores and estimates unchanged |
|
||||
|
||||
Reference in New Issue
Block a user