forked from 1b-agent/opencadstudio-upstream
refactor(scene): group modules into role-based subfolders
Move the 30 flat modules under src/scene/ into six folders by role: convert (entity→geometry), text (fonts/shaping), model (render models), pick (hit-test/selection/grips/xclip), view (camera/transform/render), cache (block + property caches). pipeline/ is unchanged. Full path migration — all `scene::X` references become `scene::<group>::X`, no compatibility re-exports. render.rs items that were `pub(super)` (parent was scene) become `pub(in crate::scene)` to keep their original scene-wide visibility. No behavior change; build and tests are green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
cd048165a9
commit
7fe7e0230d
160 files changed
+732
-715
No files matched your search
@@ -0,0 +1,63 @@
|
||||
// System TrueType/OpenType font discovery.
|
||||
//
|
||||
// Wraps a `fontdb` database loaded with the user's installed system fonts so
|
||||
// the rest of the app can (a) list available font families for the text-style
|
||||
// picker and (b) borrow a face's raw bytes to extract glyph outlines (see the
|
||||
// TTF glyph engine). LFF stroke fonts stay separate — this is purely the
|
||||
// TrueType side of the renderer.
|
||||
|
||||
use std::sync::OnceLock;
|
||||
|
||||
struct SysFonts {
|
||||
db: fontdb::Database,
|
||||
/// Sorted, de-duplicated family names for the picker.
|
||||
families: Vec<String>,
|
||||
}
|
||||
|
||||
static FONTS: OnceLock<SysFonts> = OnceLock::new();
|
||||
|
||||
fn fonts() -> &'static SysFonts {
|
||||
FONTS.get_or_init(|| {
|
||||
let mut db = fontdb::Database::new();
|
||||
db.load_system_fonts();
|
||||
|
||||
let mut families: Vec<String> = db
|
||||
.faces()
|
||||
.filter_map(|face| face.families.first().map(|(name, _)| name.clone()))
|
||||
.collect();
|
||||
families.sort_by_key(|n| n.to_lowercase());
|
||||
families.dedup();
|
||||
|
||||
SysFonts { db, families }
|
||||
})
|
||||
}
|
||||
|
||||
/// All installed system font families, sorted case-insensitively, de-duped.
|
||||
pub fn families() -> &'static [String] {
|
||||
&fonts().families
|
||||
}
|
||||
|
||||
/// Resolve a family name to a concrete face id (regular weight/style).
|
||||
fn face_id(family: &str) -> Option<fontdb::ID> {
|
||||
let db = &fonts().db;
|
||||
let query = fontdb::Query {
|
||||
families: &[fontdb::Family::Name(family)],
|
||||
..Default::default()
|
||||
};
|
||||
db.query(&query)
|
||||
}
|
||||
|
||||
/// Borrow the raw face bytes for `family` and run `f` over them. The byte slice
|
||||
/// is only valid inside the closure, so callers extract everything they need
|
||||
/// (e.g. flattened glyph outlines) before returning. `index` is the face index
|
||||
/// within a TrueType collection. Returns `None` if the family is unknown.
|
||||
pub fn with_face_data<T>(family: &str, f: impl FnOnce(&[u8], u32) -> T) -> Option<T> {
|
||||
let id = face_id(family)?;
|
||||
fonts().db.with_face_data(id, f)
|
||||
}
|
||||
|
||||
/// Whether `family` matches an installed system font (case-insensitive via
|
||||
/// fontdb's own matching).
|
||||
pub fn has_family(family: &str) -> bool {
|
||||
face_id(family).is_some()
|
||||
}
|
||||
Reference in new issue
Block a user