Compare commits

..
Author SHA1 Message Date
Brandon Thomas 985ed6e492 Merge main into PR #752 2026-10-12 00:20:57 -04:00
Brandon ThomasandClaude Opus 5.5 c4588380e7 Release workflow: pass the Azure signing secrets so Windows builds are signed
Since the release workflow moved to storytold/craft-common-actions, it has
passed only the Apple and WINDOWS_CERTIFICATE secrets. The signing job reads
values from the release environment, but only for names the caller lists, so
the AZURE_* names that Trusted Signing uses came through empty and Windows
builds would ship unsigned. Same fix as storytold/craft-launcher#174.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:03:25 -04:00
+13 -44
View File
@@ -306,12 +306,6 @@ pub struct FontDb {
/// System fallback state: enabled, and characters no system font covers.
#[cfg(not(target_arch = "wasm32"))]
sys: Mutex<SysFallback>,
/// Held through a system fallback search, so searches run one at a time. Without it a search
/// racing another that was still loading a preferred family ("Padauk" for Myanmar) skipped
/// that family as already tried and loaded whatever the coverage index found first (only
/// Padauk Bold), so which face a character fell back to depended on thread timing.
#[cfg(not(target_arch = "wasm32"))]
searching: Mutex<()>,
/// The characters each installed font file maps, read the first time a fallback search
/// needs that file. Held through a search, so two searches never read a file twice.
#[cfg(not(target_arch = "wasm32"))]
@@ -847,8 +841,6 @@ impl FontDb {
#[cfg(not(target_arch = "wasm32"))]
sys: Mutex::new(SysFallback { enabled: true, ..Default::default() }),
#[cfg(not(target_arch = "wasm32"))]
searching: Mutex::new(()),
#[cfg(not(target_arch = "wasm32"))]
coverage: Mutex::new(CoverageIndex::default()),
#[cfg(not(target_arch = "wasm32"))]
catalog_gen: AtomicU32::new(0),
@@ -1284,13 +1276,9 @@ impl FontDb {
return hit.clone();
}
}
let (found, n) = self.search_fallback(c, exclude);
// Keyed by the face count the answer was chosen from (a system fallback may have loaded
// fonts, and another thread may have loaded more since: an answer from before that load
// is returned but not cached under the new count).
if n != self.read_faces().len() {
return found;
}
let found = self.search_fallback(c, exclude);
// Keyed by the face count after the search (a system fallback may have loaded fonts).
let n = self.read_faces().len();
let mut cache = self.fallbacks.write().unwrap_or_else(|e| e.into_inner());
if cache.faces != n || cache.map.len() >= FALLBACK_CACHE_MAX {
cache.map.clear();
@@ -1300,36 +1288,17 @@ impl FontDb {
found
}
/// The fallback face for `c`, and the number of loaded faces it was chosen from.
fn search_fallback(&self, c: char, exclude: u32) -> (Option<Arc<FontFace>>, usize) {
let (found, n) = self.loaded_fallback(c, exclude);
if found.is_some() {
return (found, n);
}
self.system_search(c, exclude)
fn search_fallback(&self, c: char, exclude: u32) -> Option<Arc<FontFace>> {
self.loaded_fallback(c, exclude).or_else(|| {
#[cfg(not(target_arch = "wasm32"))]
if self.system_fallback(c) {
return self.loaded_fallback(c, exclude);
}
None
})
}
/// [`Self::search_fallback`] when no loaded face covers `c`: load a system font that does,
/// one search at a time.
#[cfg(not(target_arch = "wasm32"))]
fn system_search(&self, c: char, exclude: u32) -> (Option<Arc<FontFace>>, usize) {
let _searching = self.searching.lock().unwrap_or_else(|e| e.into_inner());
// A search that held the lock first may have loaded a font covering `c`: choose among the
// loaded faces again before loading more.
let (found, n) = self.loaded_fallback(c, exclude);
if found.is_none() && self.system_fallback(c) {
return self.loaded_fallback(c, exclude);
}
(found, n)
}
#[cfg(target_arch = "wasm32")]
fn system_search(&self, _c: char, _exclude: u32) -> (Option<Arc<FontFace>>, usize) {
(None, self.read_faces().len())
}
/// The best loaded face covering `c`, and the number of loaded faces it was chosen from.
fn loaded_fallback(&self, c: char, exclude: u32) -> (Option<Arc<FontFace>>, usize) {
fn loaded_fallback(&self, c: char, exclude: u32) -> Option<Arc<FontFace>> {
let faces = self.read_faces();
let mut order: Vec<&Arc<FontFace>> = faces.iter().filter(|f| f.id != exclude).collect();
// Right-to-left letters prefer a font made for the script, so a word isn't split across
@@ -1346,7 +1315,7 @@ impl FontDb {
let complex = crate::needs_layout_tables(c);
let shaping = |f: &FontFace| if complex { (!f.has_layout_tables(), crate::fallback_rank(c, &f.family)) } else { (false, 0) };
order.sort_by_key(|f| (rank(f), shaping(f), !f.family.eq_ignore_ascii_case(FALLBACK_FAMILY), f.italic, (f.weight - 400.0).abs() as i32));
(order.into_iter().find(|f| f.covers(c)).cloned(), faces.len())
order.into_iter().find(|f| f.covers(c)).cloned()
}
/// Load a system font covering `c` (preferred fallback families first, then any cataloged