diff --git a/crates/fonts/src/shx/tests.rs b/crates/fonts/src/shx/tests.rs index f918e4645..bb7436b64 100644 --- a/crates/fonts/src/shx/tests.rs +++ b/crates/fonts/src/shx/tests.rs @@ -473,6 +473,9 @@ fn hebrew_letters_draw_from_their_one_byte_places() { // DOS 862: bet at 0x81 advances one unit. assert!((draws(hebrew_font(0x80..=0x9A), 'ב') - 1.0).abs() < 1e-9); assert_eq!(hebrew_font(0x80..=0x9A).hebrew_places(), (false, true)); + // The old degree sign at 127 isn't a letter in DOS 862: `%%d` still draws from it + // (127 & 0x1F = 31 units). + assert!((draws(hebrew_font((0x80..=0x9A).chain([127])), '°') - 31.0).abs() < 1e-9); // A Cyrillic-style font (0xC0..0xFF all drawn) is not read as Hebrew: the letter comes // from the built-in stroke font instead of a Cyrillic shape. let cyr = hebrew_font(0xC0..=0xFF); diff --git a/crates/fonts/src/shx/text.rs b/crates/fonts/src/shx/text.rs index 82ef71a0b..c7da188ed 100644 --- a/crates/fonts/src/shx/text.rs +++ b/crates/fonts/src/shx/text.rs @@ -88,9 +88,10 @@ fn candidates(c: char, font: &ShxFont) -> [Option; 4] { _ => None, }; if let Some((s, latin, old)) = special { - // In a DOS 862 Hebrew font 127–129 are letters and 0xB0.. box drawing: shape 256–258 only. + // In a DOS 862 Hebrew font 128–129 are letters and 0xB0.. box drawing: shape 256–258, + // and the old degree sign 127 (not a letter there). if !unicode && font.kind() == ShxKind::Shapes && font.hebrew_places().1 { - return [Some(s), None, None, None]; + return [Some(s), (old == 127).then_some(old), None, None]; } return if unicode { [code(u), code(if c == '⌀' { 0x2205 } else { latin }), Some(s), Some(old)] diff --git a/crates/fonts/src/ttf.rs b/crates/fonts/src/ttf.rs index c45c0118b..5125d0a24 100644 --- a/crates/fonts/src/ttf.rs +++ b/crates/fonts/src/ttf.rs @@ -1324,7 +1324,7 @@ mod family_tests { let _ = std::os::unix::fs::symlink(&root, real.join("up")); let found = scan_dirs(&[root.join("link")], true); assert!(found.contains_key("linkedface"), "{found:?}"); - assert_eq!(shx_dirs(&[root.clone()]).len(), 1, "the folder with the SHX file, once"); + assert_eq!(shx_dirs(std::slice::from_ref(&root)).len(), 1, "the folder with the SHX file, once"); let _ = std::fs::remove_dir_all(&root); } diff --git a/crates/ui-egui/src/canvas/draw.rs b/crates/ui-egui/src/canvas/draw.rs index 34316374a..17da084f7 100644 --- a/crates/ui-egui/src/canvas/draw.rs +++ b/crates/ui-egui/src/canvas/draw.rs @@ -226,7 +226,7 @@ pub(super) fn draw_drag_gpu( let key = { use std::hash::{Hash, Hasher}; let mut h = std::collections::hash_map::DefaultHasher::new(); - (c.key, band, bg.0, bg.1, bg.2, &drag.handles, transparency).hash(&mut h); + (c.key, band, bg.0, bg.1, bg.2, &drag.handles, transparency, super::list::font_generation()).hash(&mut h); if drag.clipboard { clipboard.1.hash(&mut h); } diff --git a/crates/ui-egui/src/canvas/list.rs b/crates/ui-egui/src/canvas/list.rs index a02a0bbd6..6b4aefa9a 100644 --- a/crates/ui-egui/src/canvas/list.rs +++ b/crates/ui-egui/src/canvas/list.rs @@ -63,11 +63,16 @@ pub(super) fn rebuilt_preview<'a>(doc: &cadcraft_doc::Drawing, ents: impl IntoIt /// A rebuild only the view asks for (a new zoom band, a pan out of the built area) runs in the /// background while the current list is drawn (see [`rebuild`]); a changed drawing, or no list /// yet, is built at once. +/// The font set text is drawn with: TrueType fonts (font folders, rescans) and SHX fonts +/// (drawing folders, font folders, the search path) can each change what text looks like. Every +/// cache of drawn geometry keys on it. +pub(super) fn font_generation() -> u64 { + cadcraft_fonts::ttf::generation().wrapping_add(cadcraft_fonts::shx::generation() << 32) +} + pub(super) fn ensure_list(app: &mut CadApp, xf: &Xf, views: &[(Bounds2, f64)], ctx: &egui::Context) { let px = 1.0 / xf.scale; - // TrueType fonts (font folders, rescans) and SHX fonts (drawing folders, font folders, - // the search path) can each change what text looks like. - let fonts = cadcraft_fonts::ttf::generation().wrapping_add(cadcraft_fonts::shx::generation() << 32); + let fonts = font_generation(); if app.canvas.font_generation != fonts { app.canvas.font_generation = fonts; app.canvas.list = None; @@ -189,7 +194,8 @@ impl OnlyList { let key = { use std::hash::{Hash, Hasher}; let mut h = std::collections::hash_map::DefaultHasher::new(); - (st.uid, st.revision, std::sync::Arc::as_ptr(&st.doc) as usize, band, &only.handles, format!("{:?}", only.extra)).hash(&mut h); + (st.uid, st.revision, std::sync::Arc::as_ptr(&st.doc) as usize, band, &only.handles, format!("{:?}", only.extra), font_generation()) + .hash(&mut h); outline.into_iter().flatten().for_each(|q| (q.x.to_bits(), q.y.to_bits()).hash(&mut h)); h.finish() }; diff --git a/crates/ui-egui/src/canvas/viewport.rs b/crates/ui-egui/src/canvas/viewport.rs index 3e065f810..202fab8c2 100644 --- a/crates/ui-egui/src/canvas/viewport.rs +++ b/crates/ui-egui/src/canvas/viewport.rs @@ -286,7 +286,8 @@ impl VpHighlight { let key = { use std::hash::{Hash, Hasher}; let mut h = std::collections::hash_map::DefaultHasher::new(); - (st.uid, st.revision, std::sync::Arc::as_ptr(&st.doc) as usize, tolerance.to_bits(), handles).hash(&mut h); + (st.uid, st.revision, std::sync::Arc::as_ptr(&st.doc) as usize, tolerance.to_bits(), handles, super::list::font_generation()) + .hash(&mut h); h.finish() }; if self.key != Some(key) {