Explore logical Unicode PDF encoding with exact ToUnicode
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
Research direction
The issue shares external Typst and Krilla implementations, including logical text code and an architecture document, but does not identify an OpenPDF file or define a requested change. Read the linked Krilla architecture and logical text implementation to understand the proposal; a concrete OpenPDF task would need to specify an integration point and acceptance criteria.
Written by the indexing model from the issue text.
Description
I am sharing an Enhanced Unicode PDF architecture developed for Typsastra. This is not a request for OpenPDF to adopt it, but a working reference that may be useful for future Unicode PDF encoding work, particularly as an alternative to relying on /ActualText.
The implementation was motivated by Khmer support but is script-independent and has been tested with multilingual complex-script content.
Implementations
Typst adapter
Converts already-shaped text into source-ordered logical units:
- Fork: https://github.com/Sovichea/typst
- Tested revision:
https://github.com/Sovichea/typst/tree/75202cf09a26a5ef5dfd0f26ab7a4fe007e1be39 - Logical-unit preparation:
https://github.com/Sovichea/typst/blob/75202cf09a26a5ef5dfd0f26ab7a4fe007e1be39/crates/typst-pdf/src/text/logical.rs
Krilla PDF backend
Implements logical CID allocation, synthetic TrueType glyphs, exact /ToUnicode, font sharding, and logical-order TJ output:
- Fork: https://github.com/Sovichea/krilla
- Tested revision:
https://github.com/Sovichea/krilla/tree/d05158cf3ebead248745f846d0397e84dfb9f2d0 - Architecture document:
https://github.com/Sovichea/krilla/blob/d05158cf3ebead248745f846d0397e84dfb9f2d0/PDF_LOGICAL_UNITS.md - Logical text implementation:
https://github.com/Sovichea/krilla/blob/d05158cf3ebead248745f846d0397e84dfb9f2d0/crates/krilla/src/text/logical.rs - Logical font mapper:
https://github.com/Sovichea/krilla/blob/d05158cf3ebead248745f846d0397e84dfb9f2d0/crates/krilla/src/text/logical_font.rs
Architecture
The boundary between shaping and PDF generation is a source-ordered logical unit:
STRUCT LogicalUnit
text: exact logical Unicode
glyphs: already-shaped positioned glyphs
visual_position: independent x and y position
END STRUCT
The contract is:
- logical text is authoritative for extraction and accessibility;
- glyphs are authoritative for appearance;
- units remain in source order;
- the PDF backend does not reshape the text.
flowchart LR
A[Logical Unicode]
B[Existing shaping engine]
C[Positioned glyphs]
D[Logical units]
E[Semantic and visual key]
F[Unique logical CID]
G[Synthetic glyph]
H[Exact ToUnicode]
I[Logical-order TJ]
J[PDF]
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
F --> H
G --> I
H --> I
I --> J
A CID is reused only when both the logical text and visual construction are identical:
semantic_key := exact Unicode + positioned glyph construction
IF semantic_key already exists
reuse its CID
ELSE
allocate a new CID
create a synthetic composite glyph
map the CID to exact Unicode through ToUnicode
END IF
Each synthetic glyph contains the unit’s shaped source glyphs as positioned TrueType components. Logical CIDs are then emitted in source order, with TJ adjustments reproducing visual placement.
Unsupported units fall back to ordinary glyph output rather than failing the document.
Possible relevance to OpenPDF
The smallest possible integration boundary would be a low-level API accepting externally shaped logical units:
INPUT
source font
exact Unicode text
positioned glyphs
OUTPUT
logical CID
synthetic visual glyph
exact ToUnicode mapping
This would not require OpenPDF to replace its shaping engine or redesign paragraph layout. OpenPDF’s existing Java2D GlyphVector output could potentially be adapted to the same interface later.
Test binary
A prebuilt Typst-compatible binary is available for testing:
https://github.com/Sovichea/typsastra/releases/tag/enhanced-unicode-v0.3.1
It supports Windows, Linux, and macOS. After downloading the appropriate archive:
typst compile input.typ output.pdf
pdftotext -enc UTF-8 output.pdf output.txt
Relevant fixture:
There is no expectation that OpenPDF adopt this implementation. I am sharing it as a tested architecture that may provide useful ideas for exact Unicode /ToUnicode encoding without depending on /ActualText.
- Dominant language
- Java
- Stars
- 4.4k
- Forks
- 714
- PR merge metrics
- No merged PRs in 30d
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from LibrePDF/OpenPDF
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 88/100
-
IndexOutOfBoundsException in PdfReaderPossibly taken @andreasrosdalw claimed this 92 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
`PdfSmartCopy` can take effectively unbounded time on nested shared Form XObjectsPossibly taken A pull request linked to this issue is open or already merged. Openbug
Difficulty 4/5 3-5 days Newbie friendliness 48/100
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 38/100
-
Difficulty 4/5 1-2 days Newbie friendliness 45/100
All issues in LibrePDF/OpenPDF
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
strimzi/strimzi-kafka-operator#13328 · 1 comment · 3 reactions ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
OpenLiberty/ci.maven#2137 ·
Maintainers usually reply within 1 day
-
Payer adjustment can exceed the balance left after copay and deductible, so claim payments add up to more than the chargePossibly taken @DG47 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
synthetichealth/synthea#1772 ·
Maintainers usually reply within 13 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
geonetwork/core-geonetwork#9592 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
NationalSecurityAgency/ghidra#10040 ·
Maintainers usually reply within 2 days