pdftract/notes/bf-o4nrq.md
jedarden 7584d209e0 docs(bf-o4nrq): document CMAP entry creation point
- Identified ToUnicodeMap::add_mapping() as primary creation point
- Located at crates/pdftract-core/src/font/cmap.rs:86-88
- Uses HashMap<Vec<u8>, Vec<char>> for storage
- Called from parse_beginbfchar() and parse_beginbfrange()
- Documents call sites and data structure for skip logic implementation

Closes bf-o4nrq
2026-07-06 13:22:58 -04:00

105 lines
3.4 KiB
Markdown

# CMAP Entry Creation Point - Documentation
## Task: Locate CMAP entry creation point
## Summary
Successfully identified the exact location in the codebase where CMAP entries are created for glyphs.
## Location Details
### Primary Creation Point
**File**: `crates/pdftract-core/src/font/cmap.rs`
**Function**: `ToUnicodeMap::add_mapping()`
**Line numbers**: 86-88
```rust
/// Add a single mapping from source bytes to destination chars.
///
/// MARKER: CMAP entry creation point - this is where individual ToUnicode
/// mappings are stored. Called by parse_beginbfchar() and parse_beginbfrange().
/// See notes/bf-e4uvb-child-1.md for documentation.
pub fn add_mapping(&mut self, src: Vec<u8>, dst: Vec<char>) {
self.mappings.insert(src, dst);
}
```
### Data Structure
**Struct**: `ToUnicodeMap` (lines 67-71)
```rust
pub struct ToUnicodeMap {
/// Mapping from source byte sequence to destination Unicode codepoints.
/// Uses `Vec<u8>` as key (source bytes) and `Vec<char>` as value (destination chars).
mappings: HashMap<Vec<u8>, Vec<char>>,
}
```
- **Key**: `Vec<u8>` - source byte sequence from PDF
- **Value**: `Vec<char>` - destination Unicode characters (supports multi-codepoint mappings like ligatures)
### Call Sites
The `add_mapping()` function is called from three locations during CMap parsing:
1. **Single-character mapping** (`parse_beginbfchar()`, line 209):
```rust
map.add_mapping(src, dst);
```
2. **Range mapping - explicit array form** (`parse_beginbfrange()`, line 279):
```rust
map.add_mapping(current.clone(), dst);
```
3. **Range mapping - contiguous form** (`parse_beginbfrange()`, line 292):
```rust
map.add_mapping(current.clone(), dst.clone());
```
## Context
### CMap Parser Structure
- **Parser**: `CMapParser` struct (line 118-121)
- **Entry point**: `CMapParser::parse()` (line 136-185)
- **Supported CMap syntax**:
- `beginbfchar` / `endbfchar`: Single-character mappings
- `beginbfrange` / `endbfrange`: Range mappings (contiguous and explicit array)
- `usecmap`: Inheritance from named CMaps (stub - emits diagnostic)
### Module Structure
The font module is located at `crates/pdftract-core/src/font/` with these key files:
- `cmap.rs`: ToUnicode CMap parser (this file)
- `encoding.rs`: Font encoding handling
- `embedded.rs`: Embedded font support
- `resolver.rs`: Character resolution logic
- `predefined_cmap.rs`: Predefined CMap support
## Next Steps for Skip Logic Implementation
To implement skip logic for CMAP entries:
1. **Modification point**: The `add_mapping()` method is the ideal place to add skip logic
2. **Filter approach**: Add a conditional check before inserting into the HashMap
3. **Configuration**: May need to pass a filter/skip configuration to `ToUnicodeMap`
4. **Alternative**: Filter at call sites before calling `add_mapping()`
## References
- Module: `crates/pdftract-core/src/font/cmap.rs`
- Primary function: `ToUnicodeMap::add_mapping()` (lines 86-88)
- Data structure: `ToUnicodeMap.mappings: HashMap<Vec<u8>, Vec<char>>` (line 70)
- Call sites: lines 209, 279, 292
## Acceptance Criteria Status
**PASS**: CMAP entry creation code location identified
**PASS**: Function/module name documented (ToUnicodeMap::add_mapping)
**PASS**: Line numbers noted (lines 86-88, plus call sites at 209, 279, 292)
**PASS**: Understanding of how entries are currently added (via HashMap::insert)