pdftract/notes/bf-1m30m.md
jedarden 6c668c7e42 docs(bf-ttbb5): document no-mapping.pdf generation verification
Successfully executed generate_unicode_recovery_fixtures_bin to create
no-mapping.pdf fixture (650 bytes). Validated PDF structure includes
custom /CustomNoMap font with /Differences encoding, non-AGL glyph
names, and no ToUnicode entry. Ground truth contains U+FFFD × 3.

Closes bf-ttbb5.
2026-07-03 16:13:27 -04:00

76 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# bf-1m30m: Generate no-mapping.pdf Fixture
**Date:** 2026-07-03
**Parent Bead:** bf-f0xqd
**Prerequisite:** bf-2g412 (Research and design approach)
## Implementation
Generated the `no-mapping.pdf` fixture using the existing Rust script:
`tests/fixtures/encoding/generate_unicode_recovery_fixtures.rs`
## Verification Results
### Acceptance Criteria - All PASS
1. **✓ Valid PDF exists**: `tests/fixtures/encoding/no-mapping.pdf` (660 bytes)
- Valid PDF 1.4 structure
- Single page with 612x792 pts (letter size)
2. **✓ Font has no ToUnicode CMap**: Verified with `grep -a "ToUnicode"`
- No `/ToUnicode` entry in font dictionary
3. **✓ Font has no standard encoding**: Verified with `pdffonts` and `grep`
- `pdffonts` shows: `Encoding: Custom`
- No `/WinAnsiEncoding`, `/MacRomanEncoding`, or `/StandardEncoding` present
4. **✓ PDF contains test text content**: Verified in content stream
- Content stream: `<g001><g002><g003> Tj`
- Codes: `[0, 1, 2]` mapped to non-AGL glyph names `/g001`, `/g002`, `/g003`
- Ground truth file: Three U+FFFD replacement characters (0xEF 0xBF 0xBD × 3)
### Font Dictionary Structure
```
/Type /Font
/Subtype /Type1
/BaseFont /CustomNoMap
/Encoding <<
/Type /Encoding
/Differences [0 /g001 /g002 /g003]
>>
```
**Key characteristics:**
- Type1 font (simplest for custom encodings)
- Custom base font name (prevents standard 14 font matching)
- Custom encoding with `/Differences` array
- Non-AGL glyph names (`/g001-3` not in Adobe Glyph List)
- No embedded font program (prevents Level 3 fingerprinting)
- No ToUnicode CMap (prevents direct Unicode mapping)
## Testing Purpose
This fixture tests the ENCODING_NO_MAPPING failure mode — the worst case for Unicode recovery:
- **Level 1 (Standard Encoding)**: FAIL — No standard encoding
- **Level 2 (AGL Lookup)**: FAIL — Glyph names not in AGL
- **Level 3 (Font Fingerprinting)**: FAIL — No embedded font program
- **Level 4 (Shape Recognition)**: FAIL/Partial — Intentionally no shape DB match
- **Fallback**: Emit U+FFFD × 3 with `GLYPH_UNMAPPED` diagnostic
## Files Modified
- `tests/fixtures/encoding/no-mapping.pdf` - Generated fixture (660 bytes)
- `tests/fixtures/encoding/no-mapping.txt` - Ground truth (3 × U+FFFD)
## Files Unchanged
- `tests/fixtures/encoding/generate_unicode_recovery_fixtures.rs` - Generation script (already existed)
- `tests/fixtures/encoding/agl-only.pdf` - Companion fixture
- `tests/fixtures/encoding/fingerprint-match.pdf` - Companion fixture
- `tests/fixtures/encoding/shape-match.pdf` - Companion fixture
## Reference
- Technical approach documented in `notes/bf-f0xqd-research.md`
- Failure Mode Taxonomy: ENCODING_NO_MAPPING