M7: the Small caps sample in Type settings draws without a box

The Small caps button in Type settings labelled itself "Aɢ", but the
small-capital G (U+0262) is missing from egui's default fonts, which the
UI uses whenever Inter isn't built in, so the button showed "A" and a box.
The sample is now a capital followed by smaller capitals laid out from
ordinary letters every UI font has. A test checks the UI fonts draw every
letter of the sample.
This commit is contained in:
Filip Strajnar
2026-10-14 21:12:39 +02:00
parent 833f0d2c27
commit 6bd87bccc6
3 changed files with 58 additions and 2 deletions
+55 -1
View File
@@ -825,7 +825,11 @@ fn text_seg(ui: &mut Ui, salt: &str, items: &[(&str, &str)], active: Option<usiz
ui.painter().rect_filled(r.shrink(2.0), CornerRadius::same(4), t.hover);
}
let col = if active == Some(i) { t.text } else { t.text_secondary };
let galley = ui.painter().layout_no_wrap((*label).to_string(), regular(11.5), col);
let galley = if *tip == "Small caps" {
small_caps_sample(ui, label, col)
} else {
ui.painter().layout_no_wrap((*label).to_string(), regular(11.5), col)
};
let gr = Rect::from_center_size(r.center(), galley.size());
let size = galley.size();
ui.painter().galley(gr.min, galley, col);
@@ -848,6 +852,33 @@ fn text_seg(ui: &mut Ui, salt: &str, items: &[(&str, &str)], active: Option<usiz
out
}
/// The Small caps sample: a capital, then its other letters as smaller capitals. Drawn from
/// ordinary capitals because the small-capital letters (`ɢ`, U+0262) are missing from many UI
/// fonts, egui's defaults among them, where they showed as a box.
fn small_caps_sample(ui: &Ui, label: &str, col: Color32) -> Arc<egui::Galley> {
let mut job = egui::text::LayoutJob::default();
let mut chars = label.chars();
let first: String = chars.next().into_iter().collect();
let rest: String = chars.map(small_capital_to_capital).collect::<String>().to_uppercase();
job.append(&first, 0.0, egui::TextFormat { font_id: regular(11.5), color: col, valign: egui::Align::BOTTOM, ..Default::default() });
job.append(&rest, 0.0, egui::TextFormat { font_id: regular(8.5), color: col, valign: egui::Align::BOTTOM, ..Default::default() });
ui.painter().layout_job(job)
}
/// The capital a small-capital letter stands for (the ones a sample uses), else the letter.
fn small_capital_to_capital(c: char) -> char {
match c {
'ɢ' => 'G',
'ʜ' => 'H',
'ɪ' => 'I',
'ʟ' => 'L',
'ɴ' => 'N',
'ʀ' => 'R',
'ʏ' => 'Y',
c => c,
}
}
/// One OpenType feature toggle; `on` None = mixed. Returns true when clicked.
fn feature_row(ui: &mut Ui, tag: &str, label: &str, on: Option<bool>, supported: bool) -> bool {
let t = Tokens::get(ui.ctx());
@@ -1136,6 +1167,29 @@ pub(crate) fn font_picker(ui: &mut Ui, current: Option<&str>, just_opened: bool)
mod tests {
use super::*;
#[test]
fn small_caps_sample_draws_only_letters_the_ui_font_has() {
let ctx = egui::Context::default();
crate::theme::install_fonts(&ctx, false, 0);
let mut shown = None;
let input = egui::RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(400.0, 300.0))), ..Default::default() };
let mut out = ctx.run_ui(input, |ui| {
shown = Some(small_caps_sample(ui, "Aɢ", Color32::WHITE));
});
out.textures_delta.clear();
let g = shown.expect("drawn");
assert_eq!(g.job.text, "AG");
let [a, rest] = g.job.sections.as_slice() else { panic!("two sections: {:?}", g.job.sections) };
assert!(rest.format.font_id.size < a.format.font_id.size, "the other letters are smaller capitals");
ctx.fonts_mut(|f| {
for sec in &g.job.sections {
assert!(f.has_glyphs(&sec.format.font_id, &g.job.text), "UI font draws {:?}", g.job.text);
}
});
assert_eq!(small_capital_to_capital('ʀ'), 'R');
assert_eq!(small_capital_to_capital('x'), 'x');
}
#[test]
fn parses_line_height_and_letter_spacing() {
assert_eq!(parse_line_height("Auto", None), Some(json!("auto")));
+1
View File
@@ -73,6 +73,7 @@ blockers.
| Date | Change | Summary |
|---|---|---|
| 2026-10-14 | minor | M7: the Small caps button in Type settings showed a box where the UI font has no small-capital `ɢ` (builds without Inter use egui's fonts); its sample is now a capital and a smaller capital, drawn from ordinary letters every UI font has. Numbers unchanged |
| 2026-10-14 | minor | M7: Home screen recent files as cards: each card shows the picture its file carries on its first page's colour, the file's icon, name and "Edited ... ago"; sort by name, creation or last change either way; a table view; a click selects, a double-click or Enter opens, arrow keys move; Open, Show in folder and Remove from recents on right-click. Numbers unchanged. |
| 2026-10-14 | minor | Lost images reported on loading (#207): a `.figcraft` file whose image member is damaged, too large or missing no longer loads in silence; each lost image (up to 20, then a count) is listed in `repairs` on `file.open` with its hash and the reason, and the app shows it as a toast. Saving still writes the file without the lost images. Numbers unchanged |
| 2026-10-14 | minor | SVG import budgets (#190): gzipped SVG is unpacked by FigCraft within 64 MiB before parsing (it was unpacked without a limit), so the nesting check sees the real document; SVG documents embedded in `<image>` data URIs share one 32 MiB budget and at most 4 levels, and one past a budget is left out. Linked files stay unread. Numbers unchanged |
+2 -1
View File
@@ -1,6 +1,6 @@
# UI and interaction parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** minor (recent files as cards; vector edit mode: hovering, hatching, selecting and dragging filled regions; home screen: Templates tab, first-run templates and Getting started tips; number fields: scrub rates, arrow steps, arithmetic with brackets, relative edits of mixed values; outline mode's hidden layers and object bounds; Hide when publishing; cursors per tool and modifier; panel widths; dark pages for files made in the dark theme; drag threshold and double-clicks into text in groups; rotation origin on Alt+R and placing with Enter: no documented shortcut missing; keyboard shortcut parity suite and bindings; cursor chat and spotlight in live sessions; layers and assets panels behaviour suite and fixes; vector multi-edit and the vector edit tail; canvas navigation, guides and grids behaviour suite and fixes; shapes and vector behaviour suite and fixes; paint and effects behaviour suite and fixes; frames, groups, sections and masks behaviour suite and fixes; layers panel keyboard: F2 rename, Shift+F10 context menu, F8 box selection; selection and transform behaviour suite and fixes; Display P3: gamut warning and soft-proof (true P3 blocked upstream); several windows; boolean hit testing on the result, group drags, frame outlines and slices; outlines for the selection, mask outlines; arc fields, live boolean editing, shape builder on strokes, one-sided widths) · **Target:** Figma Design UI3 (desktop app 126.10.7)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** minor (the Small caps sample in Type settings drawn from capitals; recent files as cards; vector edit mode: hovering, hatching, selecting and dragging filled regions; home screen: Templates tab, first-run templates and Getting started tips; number fields: scrub rates, arrow steps, arithmetic with brackets, relative edits of mixed values; outline mode's hidden layers and object bounds; Hide when publishing; cursors per tool and modifier; panel widths; dark pages for files made in the dark theme; drag threshold and double-clicks into text in groups; rotation origin on Alt+R and placing with Enter: no documented shortcut missing; keyboard shortcut parity suite and bindings; cursor chat and spotlight in live sessions; layers and assets panels behaviour suite and fixes; vector multi-edit and the vector edit tail; canvas navigation, guides and grids behaviour suite and fixes; shapes and vector behaviour suite and fixes; paint and effects behaviour suite and fixes; frames, groups, sections and masks behaviour suite and fixes; layers panel keyboard: F2 rename, Shift+F10 context menu, F8 box selection; selection and transform behaviour suite and fixes; Display P3: gamut warning and soft-proof (true P3 blocked upstream); several windows; boolean hit testing on the result, group drags, frame outlines and slices; outlines for the selection, mask outlines; arc fields, live boolean editing, shape builder on strokes, one-sided widths) · **Target:** Figma Design UI3 (desktop app 126.10.7)
Fine canvas control is what Figma users feel first: handles, snapping, nudging, modifier keys,
drag behaviour, numeric precision. This checklist covers the tools, gestures and panels. Status:
@@ -164,6 +164,7 @@ in the table. `crates/ui-egui/src/shortcut_keys_tests.rs` drives the keys a look
| Date | Change | Summary |
|---|---|---|
| 2026-10-14 | minor | Type settings: the Small caps button draws its sample as a capital and a smaller capital, no longer as a box where the UI font lacks the small-capital letter (egui's default fonts) |
| 2026-10-14 | minor | Home screen recent files as cards with thumbnails on their page colour, a sortable table view, selection, keyboard and a context menu |
| 2026-10-13 | minor | Vector edit mode regions: with the Move tool the filled area under the pointer is hatched with "/" lines in the selection colour (about 1.4 px), clipped by the area's own fill rule so holes stay clear, and the hatch goes when the pointer is 3.5 px from a point or 2 px from a segment (screen pixels at any zoom); the spacing follows octave folding, fitted to measurements at several zoom levels (8 px at every power-of-two zoom, the gap growing with the zoom and stepping back at √2 · 2ⁿ), anchored to the vector so it doesn't slide when panning, one continuous pattern across selected areas; a click selects an area with its points (they move with it but keep the unselected look), Shift adds an area or takes a selected one out, a press on a selected area drags everything selected, drags show no hover hatch, a click on an empty spot (such as a hole) clears the areas and stays in edit mode, the last area listed wins where areas overlap, only filled vectors have areas; `vector.edit.select {regions}` and `vector.edit.state` report them (`regions_tests`, `vector_regions_tests`) |
| 2026-10-13 | minor | Home screen: a Templates tab (eight starter templates as cards with thumbnails, search and a kind filter; click or Enter opens a new document) replaces the Community placeholder, the Drafts placeholder is removed, Recents offers four templates while there are no recent files and shows a Getting started card (closable; Help ▸ Getting started brings it back), File ▸ New from template…, and a first run opens on the home screen |