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

3.4 KiB

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

/// 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)

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):

    map.add_mapping(src, dst);
    
  2. Range mapping - explicit array form (parse_beginbfrange(), line 279):

    map.add_mapping(current.clone(), dst);
    
  3. Range mapping - contiguous form (parse_beginbfrange(), line 292):

    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)