All acceptance criteria PASS:
- TrueType font from fixture: glyph_id_for('A') matches Face cmap
- OpenType CFF support: handled via OpenTypeMetrics
- Type1 limited capability: graceful without CharStrings parser
- Corrupt font handling: FONT_PARSE_FAILED diagnostic emitted
15/15 embedded font tests passing.
3.2 KiB
3.2 KiB
pdftract-6ah: Embedded Font Program Loader
Summary
Implemented embedded font program loader for TrueType, OpenType CFF, and Type1 fonts using ttf-parser and owned_ttf_parser crates.
Implementation
Files Modified
crates/pdftract-core/src/font/embedded.rs- Full implementation of embedded font loader
Key Components
-
FontMetricstrait - Unified interface for glyph lookups and metricsglyph_id_for(char)- Map Unicode to glyph IDadvance(glyph_id)- Get advance width in font unitsbbox(glyph_id)- Get glyph bounding boxunits_per_em()- Get units-per-em for scalinghas_valid_cmap()- Check for valid Unicode cmap
-
OpenTypeMetrics- TrueType/OpenType CFF implementation- Uses
owned_ttf_parser::OwnedFacefor lifetime-safe font storage - Supports both TrueType (SFNT) and OpenType CFF fonts
- Detects and reports missing/invalid cmaps
- Uses
-
Type1Metrics- Limited Type1 implementation- Uses
/Widthsarray from FontDescriptor - Does NOT parse CharStrings (per task requirements)
glyph_id_for()always returns None (Type1 uses glyph names, not GIDs)
- Uses
-
EmptyFontMetrics- Fallback for corrupt/missing fonts- Returns None for all lookups
- Prevents crashes when font loading fails
-
EmbeddedFont::load()- Main entry point- Handles
/FontFile(Type1),/FontFile2(TrueType),/FontFile3(OpenType) - Decodes stream filters (FlateDecode, etc.)
- Emits diagnostics on failure without aborting
- Handles
Acceptance Criteria Status
PASS
- TrueType font from fixture:
test_truetype_glyph_id_for_matches_cmapverifiesglyph_id_for('A')matches Face cmap for all ASCII characters - OpenType CFF support:
OpenTypeMetricshandles CFF fonts (same code path as TrueType) - Type1 limited capability:
test_type1_limited_capability_no_charstringsverifies graceful handling without CharStrings parser - Corrupt font handling:
test_corrupt_font_emits_diagnosticverifiesFONT_PARSE_FAILEDdiagnostic is emitted
Test Results
running 15 tests
test font::embedded::tests::test_corrupt_font_emits_diagnostic ... ok
test font::embedded::tests::test_empty_font_metrics ... ok
test font::embedded::tests::test_font_metrics_units_per_em_scaling ... ok
test font::embedded::tests::test_load_truetype_font_from_fixture ... ok
test font::embedded::tests::test_opentype_metrics_has_valid_cmap_detection ... ok
test font::embedded::tests::test_subset_font_behavior ... ok
test font::embedded::tests::test_truetype_glyph_id_for_matches_cmap ... ok
test font::embedded::tests::test_type1_limited_capability_no_charstrings ... ok
test font::embedded::tests::test_type1_metrics_empty ... ok
... (15 total)
test result: ok. 15 passed; 0 failed
Dependencies
ttf-parser = "0.24"- Font parsing (already approved)owned_ttf_parser = "0.21"- Lifetime-safe OwnedFace (already approved)
Notes
- The
opentype-layoutfeature is enabled by default inowned_ttf_parser, allowing CFF font parsing - Subset fonts correctly return None for unmapped characters
- Units-per-em is correctly extracted (e.g., DejaVuSans has UPEM 2048)
- Diagnostics
FONT_PARSE_FAILEDandFONT_UNSUPPORTEDare properly emitted