3.6 KiB
3.6 KiB
ToUnicode Entry Creation Code Search
Task: Search and identify ToUnicode entry creation code Bead: bf-29ioc Date: 2026-07-05
Primary Location
File: /home/coding/pdftract/crates/pdftract-core/src/font/cmap.rs
Core Function: ToUnicodeMap::add_mapping()
Lines: 86-88
/// 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);
}
This is the primary entry creation point where individual ToUnicode mappings are stored in the internal HashMap.
Functions that Call add_mapping()
1. parse_beginbfchar()
Lines: 190-216
- Called at line 209:
map.add_mapping(src, dst); - Handles single-character mappings from
beginbfchar...endbfcharblocks - Format:
beginbfchar <count> <src1> <dst1> <src2> <dst2> ... endbfchar
2. parse_beginbfrange() - Two Forms
Lines: 223-309
a) Explicit Array Form (line 279):
map.add_mapping(current.clone(), dst);
- Format:
beginbfrange <count> <lo> <hi> [<d0> <d1> ...] endbfrange - Each element in the array is mapped individually
b) Contiguous Range Form (line 292):
map.add_mapping(current.clone(), dst.clone());
- Format:
beginbfrange <count> <lo> <hi> <dst> endbfrange - Range is expanded with incrementing destination values
Public Parser Functions
parse_to_unicode()(line 493) - Convenience function, returns map onlyparse_to_unicode_with_diags()(line 502) - Returns map + diagnostics
Related Test Functions
Lines 508-732 contain comprehensive tests:
test_parse_single_bfchar(line 520)test_parse_bfchar_ligature(line 532)test_parse_bfrange_contiguous(line 570)test_parse_bfrange_explicit_array(line 586)- And 14 more tests covering edge cases
Usage Location (Query Side)
File: /home/coding/pdftract/crates/pdftract-core/src/font/resolver.rs
resolve_level1() Function
Lines: 383-399
fn resolve_level1(char_code: &[u8], to_unicode: Option<&ToUnicodeMap>) -> ResolvedGlyph {
let Some(cmap) = to_unicode else {
return ResolvedGlyph::failure();
};
let Some(chars) = cmap.lookup(char_code) else {
return ResolvedGlyph::failure();
};
// ... returns resolved glyph with UnicodeSource::ToUnicode
}
This function queries the ToUnicode entries created by add_mapping(), using ToUnicodeMap::lookup() (line 93-95 in cmap.rs).
Summary
| Aspect | Location | Lines |
|---|---|---|
| Entry creation | cmap.rs::ToUnicodeMap::add_mapping() |
86-88 |
| Single mapping parser | cmap.rs::parse_beginbfchar() |
190-216 (calls at 209) |
| Range mapping parser | cmap.rs::parse_beginbfrange() |
223-309 (calls at 279, 292) |
| Entry query/lookup | cmap.rs::ToUnicodeMap::lookup() |
93-95 |
| Usage in resolver | resolver.rs::resolve_level1() |
383-399 |
Data Structure
The ToUnicodeMap struct (lines 67-71 in cmap.rs) stores:
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>>,
}
This allows:
- Variable-length source byte sequences (1-4 bytes)
- Multi-codepoint destinations (for ligature expansion like
fi→ U+0066 U+0069)