Commit Graph
13 Commits
Author SHA1 Message Date
Abimael MartellandClaude Opus 4.6 f1b32b320b fix(fonts): prefer TrueType cmap over sequential remap for CJK subset fonts
Subset fonts number GIDs by document encounter order, not sorted order.
The sequential remap scrambled character mappings, losing 2,532+ CJK
characters. Now promotes TrueType cmap fallback when it has more entries
than the primary ToUnicode CMap. Also adds CJK scoring to score_text()
as defense-in-depth.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:37:42 -07:00
Abimael MartellandClaude Opus 4.6 a4a2e1f267 Fix PUA glyph decoding, Symbol font cmap mapping, and UTF-8 detection
- Strip PUA F000 offset for "uniF0XX" glyph names (e.g. uniF072 → 'r')
- Use Mac Roman/Symbol cmap subtables for proper code→GID→Unicode mapping
  instead of assuming GID equals character code in subsetted fonts
- Skip fallback CMap building for fonts with explicit encoding
- Move UTF-8 detection before lopdf single-byte encoding decoder

Fixes systematic letter substitutions (CITY→CITQ), missing French letters,
and UTF-8 mojibake (José→José). Eval: missing_text -32%, encoding_issue 7→4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:54:12 -08:00
Abimael Martell 97910e86bf fix specific decoding issues 2026-02-20 21:16:12 -08:00
Abimael MartellandClaude Opus 4.6 65e305d544 feat: Improve CMap handling with binary CMap support, inline ToUnicode, and fallback decoding
- Add pdf.js binary CMap (bcmap) parser for Japan1/GB1/CNS1 CID fonts
- Support inline ToUnicode streams (not just object references)
- Add CMapDecisionCache for heuristic primary vs remapped CMap selection
- Build fallback CMaps from embedded font data and CIDSystemInfo
- Handle simple fonts without ToUnicode via embedded font cmap
- Add Symbol/Wingdings/ZapfDingbats font decoding fallback
- Support usecmap chaining in both text and binary CMap formats
- Scan XObject Forms for text operators in detector
- Change default detection strategy from EarlyExit to Sample(8)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:47:10 -08:00
Abimael MartellandClaude Opus 4.6 66c88a4fc9 fix(tounicode): Remap broken ToUnicode CMaps from subset fonts with GID mismatch
Some PDF generators subset-embed fonts by renumbering GIDs sequentially
but fail to update the ToUnicode CMap, which still references original
GID values. Detect this mismatch (Identity-H, no CIDToGIDMap, W array
starts at CID ≤ 2 but CMap min CID > 2) and remap to sequential positions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 14:12:30 -08:00
Abimael MartellandClaude Opus 4.6 421690c7c4 fix(fonts): Fix decoding for custom encodings and CID Korean fonts
Merge CMap and Differences encoding at the byte level for single-byte
fonts, fixing garbled output when partial ToUnicode CMaps caused Latin-1
fallback to block the Differences path. Add Adobe-Korea1 CID-to-Unicode
predefined mapping for Identity-H CID fonts without ToUnicode streams,
and support TrueType cmap extraction via ttf-parser for embedded fonts.
Also handle suffixed glyph names (e.g. zero.tf, a.ss01) per Adobe spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:32:11 -08:00
Abimael MartellandClaude Opus 4.6 a00ce46ab0 refactor(tounicode): Replace raw byte scanning with lopdf document model for CMap extraction
Eliminates double-parsing of PDFs by using the lopdf document model exclusively
for ToUnicode CMap extraction. The old raw byte scanner parsed PDFs separately
from lopdf and only handled FlateDecode, while lopdf handles FlateDecode + LZW +
ASCII85. The new approach walks page fonts and Form XObject fonts via the document
API, yielding ~7x speedup on text-heavy PDFs and ~1.2x overall.

- Add FontCMaps::from_doc() with recursive Form XObject font walking
- Remove ~270 lines of raw byte scanning code (from_pdf_bytes, extract_stream_from_raw_pdf, etc.)
- Remove flate2 dependency (lopdf handles decompression internally)
- Remove dead CMap lookup fallback branches (by_name, get_with_obj, base_font_name)
- Remove unused font_base_names parameter from extract_text_from_operand
- Skip U+FFFD replacement characters in CMap decode (PDF notdef glyph markers)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:33:32 -08:00
Abimael Martell 5401354f2e add logging 2026-02-18 10:34:32 -08:00
Abimael MartellandClaude Opus 4.6 350bbc0086 feat(cli): Add --pages and --select-pages flags, fix CMap matching and whitespace tracking
- Add --pages flag to insert <!-- Page N --> markers between pages
- Add --select-pages flag to process only specific pages (e.g. 1,3,5-10)
- Wire MarkdownOptions and page filter through process_pdf_with_config
- Fix fuzzy CMap matching that caused Cyrillic substitution on Latin text
- Fix whitespace Tj items not advancing text matrix (broke gap detection)
- Tighten single-char fragment join threshold from 0.25 to 0.20
- Gitignore debug/diagnostic binaries and remove tracked ones

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:58:58 -08:00
Abimael MartellandClaude Opus 4.6 b929bbd92e perf(extractor): Cache font encodings to avoid re-parsing CMap per text op
lopdf's get_font_encoding() re-parses ToUnicode CMap streams via nom for
every Tj/TJ operator. Cache the encoding once per font during page setup.
Also add binary search for CMap range lookup and de-dup CMap extraction.

Reduces Arabic PDF processing from 45s to <1s (53x speedup).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:47 -08:00
Abimael Martell 8d0ce9ea0a fix(encoding): Fix CJK/Unicode encoding bug 2026-02-11 12:33:06 -08:00
Abimael Martell 3d6772fc20 improve spacing detection, and layout detection 2026-02-09 12:45:08 -08:00
Abimael Martell ec96311a65 implement ToUnicode CMap support for proper text extraction from PDFs with custom font encodings 2026-02-09 09:46:07 -08:00