Pass the original filename to file.openBytes so the engine removes one native extension. Cover Open and Drop, repeated suffixes, Unicode, bare and missing extensions, and IDML through the import inbox. Keep the full filename in import warnings.
Co-Authored-By: OpenAI Codex <noreply@openai.com>
A font with no readable OS/2 table doesn't say what its licence allows,
and reporting fsType 0 made it look installable. FontFace::fs_type() now
returns None for it, and font.list reports fsType and the five flags as
null. restricted_licence() and bitmap_only() still treat it as
unrestricted, so export behaviour doesn't change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApvpyStzzHbKyDBNxpzn2Y
Found while testing crates/textimport/src/export.rs:18 (plain_char) and :177 (rtf)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/epub/src/html.rs:47-54 (reading_order: the `it.hidden` check comes after the group's children are pushed)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
file.openBytes used the name it was given as the document's title as is. The
IDML path strips .idml/.indd/.indt, but a native document opened as
"Brochure.designcraft" kept the extension, and everything that adds it back
doubled it: Save in the browser downloaded Brochure.designcraft.designcraft,
Save As suggested that name, and the File Name variable showed it. The app's
own drop and open paths strip the extension before calling, so only hosts and
scripts that pass a file name hit it.
The title now drops one trailing .designcraft (any case). Other names are
unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApvpyStzzHbKyDBNxpzn2Y
font.list now gives, for the face that sets the text, its raw OS/2 fsType
and what the bits mean: restrictedLicence, bitmapOnly, noSubsetting,
editable and previewPrint (null when the face is missing). A host that
makes print PDFs can then refuse a face whose licence doesn't allow the
export, including system fonts and the bundled fonts, without reading the
font files itself. PDF export subsets every font, so a caller needs
noSubsetting as well as the restricted and bitmap-only bits.
FontFace gains fs_type(); restricted_licence() and bitmap_only() read it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApvpyStzzHbKyDBNxpzn2Y
Found while testing crates/engine/src/math.rs:909 (to_svg, the `esc` closure used for each <text> glyph)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/color/src/lib.rs:115 (Color::to_hsb, the `max == r` branch)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>