* Encode text to a PDF string for the given font. * * Standard 14 fonts use WinAnsiEncoding (or SymbolEncoding/ZapfDingbatsEncoding). * Unencodable characters are substituted with .notdef (byte 0x00). * Embedded fonts use Identity-H encoding with glyph IDs.
(text: string, font: FontInput)
| 2753 | * Embedded fonts use Identity-H encoding with glyph IDs. |
| 2754 | */ |
| 2755 | private encodeTextForFont(text: string, font: FontInput): PdfString { |
| 2756 | if (typeof font === "string") { |
| 2757 | // Standard 14 font - use the appropriate encoding |
| 2758 | const encoding = getEncodingForStandard14(font); |
| 2759 | const codes: number[] = []; |
| 2760 | |
| 2761 | for (const char of text) { |
| 2762 | if (encoding.canEncode(char)) { |
| 2763 | // biome-ignore lint/style/noNonNullAssertion: canEncode guarantees getCode succeeds |
| 2764 | codes.push(encoding.getCode(char.codePointAt(0)!)!); |
| 2765 | } else { |
| 2766 | // Substitute unencodable characters with .notdef (byte 0x00) |
| 2767 | codes.push(0x00); |
| 2768 | } |
| 2769 | } |
| 2770 | |
| 2771 | const bytes = new Uint8Array(codes); |
| 2772 | |
| 2773 | // Use hex format for defense-in-depth: hex strings are pure ASCII |
| 2774 | // and immune to any string encoding transformation |
| 2775 | return PdfString.fromBytes(bytes); |
| 2776 | } |
| 2777 | |
| 2778 | // Embedded font - use Identity-H encoding with GIDs |
| 2779 | // With CIDToGIDMap /Identity, the content stream must contain glyph IDs |
| 2780 | const gids = font.encodeTextToGids(text); |
| 2781 | const bytes = new Uint8Array(gids.length * 2); |
| 2782 | |
| 2783 | for (let i = 0; i < gids.length; i++) { |
| 2784 | const gid = gids[i]; |
| 2785 | bytes[i * 2] = (gid >> 8) & 0xff; |
| 2786 | bytes[i * 2 + 1] = gid & 0xff; |
| 2787 | } |
| 2788 | |
| 2789 | return PdfString.fromBytes(bytes); |
| 2790 | } |
| 2791 | |
| 2792 | // ───────────────────────────────────────────────────────────────────────────── |
| 2793 | // Text Extraction |
no test coverage detected