mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-05 01:49:41 -06:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d48ef088c1 | ||
|
|
279608787b | ||
|
|
1870455f66 |
@@ -304,7 +304,12 @@ impl Dictionary {
|
||||
|
||||
/// `w` made of dictionary parts allowed in compounds (`COMPOUNDFLAG`, or the begin, middle and
|
||||
/// end flags), each at least `COMPOUNDMIN` characters long.
|
||||
fn compounded(&self, w: &[char], index: usize) -> bool {
|
||||
fn compounded(&self, w: &[char], index: usize, failed: &mut HashSet<(usize, usize)>) -> bool {
|
||||
// `w` is always a tail of the checked word, so its length names it: a (tail, part index)
|
||||
// that failed once fails again however the earlier parts were split.
|
||||
if failed.contains(&(w.len(), index)) {
|
||||
return false;
|
||||
}
|
||||
if self.compound.is_none() && self.compound_end.is_none() {
|
||||
return false;
|
||||
}
|
||||
@@ -322,10 +327,11 @@ impl Dictionary {
|
||||
if [self.compound, self.compound_end].into_iter().flatten().any(|f| self.compound_part(rest, f, true)) {
|
||||
return true;
|
||||
}
|
||||
if self.compounded(rest, index + 1) {
|
||||
if self.compounded(rest, index + 1, failed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
failed.insert((w.len(), index));
|
||||
false
|
||||
}
|
||||
|
||||
@@ -352,7 +358,7 @@ impl Dictionary {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
self.compounded(&w, 0)
|
||||
self.compounded(&w, 0, &mut HashSet::new())
|
||||
}
|
||||
|
||||
/// Is `word` spelt correctly? Capitalised and upper-case forms of a lower-case word pass.
|
||||
@@ -931,6 +937,17 @@ SFX D Y 1\nSFX D 0 ed/S .\n";
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlapping_compound_roots_with_a_failing_ending_stay_cheap() {
|
||||
// Roots a..aaaaaaaa overlap, so many splits of "aaa…ab" reach the same (tail, part) state; unmemoized that is millions of searches.
|
||||
let d = Dictionary::parse(
|
||||
b"COMPOUNDFLAG X\nCOMPOUNDMIN 1\n".as_slice(),
|
||||
b"8\na/X\naa/X\naaa/X\naaaa/X\naaaaa/X\naaaaaa/X\naaaaaaa/X\naaaaaaaa/X\n".as_slice(),
|
||||
);
|
||||
assert!(!d.check(&format!("{}b", "a".repeat(99))));
|
||||
assert!(d.check(&"a".repeat(20)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn runs_give_words_their_language() {
|
||||
use deckcraft_model::{Paragraph, Run, RunProps};
|
||||
|
||||
@@ -169,7 +169,7 @@ impl FontDb {
|
||||
if bundled.contains(fam) {
|
||||
continue;
|
||||
}
|
||||
if self.is_loaded(fam) || (self.system_fallback_enabled() && self.has_family(fam)) {
|
||||
if self.is_loaded(fam) || self.has_family(fam) {
|
||||
let f = self.face(fam, style);
|
||||
if f.family.eq_ignore_ascii_case(fam) && covers_cluster(&f, cluster) {
|
||||
return f;
|
||||
|
||||
@@ -976,17 +976,6 @@ impl FontDb {
|
||||
let _ = on;
|
||||
}
|
||||
|
||||
/// Whether automatic system-font lookups (fallback by character, symbol and script families)
|
||||
/// may touch installed fonts. Lookups of a family the document or host names are not gated.
|
||||
pub(crate) fn system_fallback_enabled(&self) -> bool {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
self.sys.lock().unwrap_or_else(std::sync::PoisonError::into_inner).enabled
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
false
|
||||
}
|
||||
|
||||
/// Process-wide database: the bundled fonts, then the installed system fonts, cataloged the
|
||||
/// first time a lookup by family name needs them (or ahead of time by
|
||||
/// [`FontDb::scan_in_background`]).
|
||||
@@ -1480,8 +1469,7 @@ impl FontDb {
|
||||
};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
let cataloged: Vec<String> =
|
||||
if self.system_fallback_enabled() { self.read_catalog().iter().map(|e| e.family.clone()).collect() } else { Vec::new() };
|
||||
let cataloged: Vec<String> = self.read_catalog().iter().map(|e| e.family.clone()).collect();
|
||||
for fam in SYSTEM_FALLBACKS.iter().filter(|f| f.contains("Symbol")) {
|
||||
if !self.is_loaded(fam) && cataloged.iter().any(|f| f.eq_ignore_ascii_case(fam)) {
|
||||
self.load_cataloged(fam);
|
||||
|
||||
@@ -425,11 +425,3 @@ fn the_font_scan_skips_fifos_folders_and_link_loops() {
|
||||
assert!(fifo || n >= 1);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn disabling_system_fallback_gates_automatic_family_loads() {
|
||||
let db = FontDb::with_font_dirs(Vec::new());
|
||||
assert!(cfg!(target_arch = "wasm32") || db.system_fallback_enabled());
|
||||
db.set_system_fallback(false);
|
||||
assert!(!db.system_fallback_enabled());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user