Skip to content

Add ufoz support#407

Open
cmyr wants to merge 2 commits into
a-general-loading-apifrom
ufoz2
Open

Add ufoz support#407
cmyr wants to merge 2 commits into
a-general-loading-apifrom
ufoz2

Conversation

@cmyr

@cmyr cmyr commented May 14, 2026

Copy link
Copy Markdown
Member

If passed a file (not a directory) and with the 'ufoz' feature enabled, norad will attempt to treat the file as a zip'd ufo directory.

@RickyDaMa RickyDaMa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are significant improvements that we could implement while everything is in flux. Sorry I don't have the time to offer to help beyond these little reviews 🙏

Comment thread src/font.rs
Comment on lines +224 to +225
#[cfg(feature = "ufoz")]
if metadata.is_file() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we only checking it's a file, not looking at the extension?

If we were ever to add JSON UFO loading, we're going to clash with this

Comment thread src/zip_source.rs
Comment on lines +15 to +17
impl ZipSource {
/// Open a zip archive at the given path and load all file entries into memory.
pub fn open(path: &Path) -> Result<Self, FontLoadError> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to just decompress what we need on the fly, instead of everything at once ahead of time?

If we store the archive in ZipSource instead of the decompressed entries. I guess the issue is that FontSource doesn't let you mutate self currently, but that could be changed or worked around I guess?

Comment thread src/zip_source.rs
Comment on lines +95 to +97
pub(crate) fn detect_zip_root<R: io::Read + io::Seek>(
archive: &mut zip::ZipArchive<R>,
) -> Option<PathBuf> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative impl that doesn't require always traversing the entire archive: pull out the first entry ahead of the loop, get its top-level dir (if it's a fileearly-return None), then run through everything else, immediately returning None if any other path doesn't have that same first component.

@cmyr cmyr force-pushed the a-general-loading-api branch from 5378f30 to 2dee764 Compare June 24, 2026 18:14
@cmyr cmyr force-pushed the a-general-loading-api branch 2 times, most recently from cc1e973 to 5b5ee69 Compare June 25, 2026 17:03
@cmyr cmyr force-pushed the a-general-loading-api branch 2 times, most recently from f4737b9 to cc6c587 Compare June 25, 2026 18:34
cmyr added 2 commits June 26, 2026 10:11
If passed a file (not a directory) and with the 'ufoz' feature enabled,
norad will attempt to treat the file as a zip'd ufo directory.
Add end-to-end integration tests for ufoz loading

Verify that loading a UFO from a zip archive via Font::load produces a
Font identical to loading the same UFO from a directory, covering the
wrapper-dir, __MACOSX, data/images, DataRequest, and error paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants