@cj-tech-master/excelts 9.4.1 → 9.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/browser/modules/pdf/builder/document-builder.js +4 -23
  2. package/dist/browser/modules/pdf/core/pdf-stream.d.ts +15 -0
  3. package/dist/browser/modules/pdf/core/pdf-stream.js +47 -3
  4. package/dist/browser/modules/pdf/font/font-manager.d.ts +37 -6
  5. package/dist/browser/modules/pdf/font/font-manager.js +129 -17
  6. package/dist/browser/modules/pdf/font/system-fonts.d.ts +41 -0
  7. package/dist/browser/modules/pdf/font/system-fonts.js +188 -0
  8. package/dist/browser/modules/pdf/font/ttf-parser.js +29 -1
  9. package/dist/browser/modules/pdf/font/type3-font.d.ts +35 -0
  10. package/dist/browser/modules/pdf/font/type3-font.js +228 -0
  11. package/dist/browser/modules/pdf/font/type3-glyphs-extended.d.ts +33 -0
  12. package/dist/browser/modules/pdf/font/type3-glyphs-extended.js +4164 -0
  13. package/dist/browser/modules/pdf/font/type3-glyphs-extended2.d.ts +16 -0
  14. package/dist/browser/modules/pdf/font/type3-glyphs-extended2.js +9649 -0
  15. package/dist/browser/modules/pdf/font/type3-glyphs-fill.d.ts +17 -0
  16. package/dist/browser/modules/pdf/font/type3-glyphs-fill.js +5438 -0
  17. package/dist/browser/modules/pdf/font/type3-glyphs-quality.d.ts +28 -0
  18. package/dist/browser/modules/pdf/font/type3-glyphs-quality.js +5345 -0
  19. package/dist/browser/modules/pdf/font/type3-glyphs.d.ts +79 -0
  20. package/dist/browser/modules/pdf/font/type3-glyphs.js +2567 -0
  21. package/dist/browser/modules/pdf/render/layout-engine.js +36 -23
  22. package/dist/browser/modules/pdf/render/page-renderer.d.ts +9 -0
  23. package/dist/browser/modules/pdf/render/page-renderer.js +110 -78
  24. package/dist/browser/modules/pdf/render/pdf-exporter.js +73 -5
  25. package/dist/cjs/modules/pdf/builder/document-builder.js +3 -22
  26. package/dist/cjs/modules/pdf/core/pdf-stream.js +49 -3
  27. package/dist/cjs/modules/pdf/font/font-manager.js +129 -17
  28. package/dist/cjs/modules/pdf/font/system-fonts.js +194 -0
  29. package/dist/cjs/modules/pdf/font/ttf-parser.js +29 -1
  30. package/dist/cjs/modules/pdf/font/type3-font.js +231 -0
  31. package/dist/cjs/modules/pdf/font/type3-glyphs-extended.js +4167 -0
  32. package/dist/cjs/modules/pdf/font/type3-glyphs-extended2.js +9652 -0
  33. package/dist/cjs/modules/pdf/font/type3-glyphs-fill.js +5441 -0
  34. package/dist/cjs/modules/pdf/font/type3-glyphs-quality.js +5348 -0
  35. package/dist/cjs/modules/pdf/font/type3-glyphs.js +2573 -0
  36. package/dist/cjs/modules/pdf/render/layout-engine.js +36 -23
  37. package/dist/cjs/modules/pdf/render/page-renderer.js +111 -78
  38. package/dist/cjs/modules/pdf/render/pdf-exporter.js +71 -3
  39. package/dist/esm/modules/pdf/builder/document-builder.js +4 -23
  40. package/dist/esm/modules/pdf/core/pdf-stream.js +47 -3
  41. package/dist/esm/modules/pdf/font/font-manager.js +129 -17
  42. package/dist/esm/modules/pdf/font/system-fonts.js +188 -0
  43. package/dist/esm/modules/pdf/font/ttf-parser.js +29 -1
  44. package/dist/esm/modules/pdf/font/type3-font.js +228 -0
  45. package/dist/esm/modules/pdf/font/type3-glyphs-extended.js +4164 -0
  46. package/dist/esm/modules/pdf/font/type3-glyphs-extended2.js +9649 -0
  47. package/dist/esm/modules/pdf/font/type3-glyphs-fill.js +5438 -0
  48. package/dist/esm/modules/pdf/font/type3-glyphs-quality.js +5345 -0
  49. package/dist/esm/modules/pdf/font/type3-glyphs.js +2567 -0
  50. package/dist/esm/modules/pdf/render/layout-engine.js +36 -23
  51. package/dist/esm/modules/pdf/render/page-renderer.js +110 -78
  52. package/dist/esm/modules/pdf/render/pdf-exporter.js +73 -5
  53. package/dist/iife/excelts.iife.js +25445 -344
  54. package/dist/iife/excelts.iife.js.map +1 -1
  55. package/dist/iife/excelts.iife.min.js +48 -46
  56. package/dist/types/modules/pdf/core/pdf-stream.d.ts +15 -0
  57. package/dist/types/modules/pdf/font/font-manager.d.ts +37 -6
  58. package/dist/types/modules/pdf/font/system-fonts.d.ts +41 -0
  59. package/dist/types/modules/pdf/font/type3-font.d.ts +35 -0
  60. package/dist/types/modules/pdf/font/type3-glyphs-extended.d.ts +33 -0
  61. package/dist/types/modules/pdf/font/type3-glyphs-extended2.d.ts +16 -0
  62. package/dist/types/modules/pdf/font/type3-glyphs-fill.d.ts +17 -0
  63. package/dist/types/modules/pdf/font/type3-glyphs-quality.d.ts +28 -0
  64. package/dist/types/modules/pdf/font/type3-glyphs.d.ts +79 -0
  65. package/dist/types/modules/pdf/render/page-renderer.d.ts +9 -0
  66. package/package.json +1 -1
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Type3 fallback font builder.
3
+ *
4
+ * Produces a PDF Type3 font object that contains vector-drawn glyphs for
5
+ * Unicode characters that cannot be represented by standard Type1 fonts
6
+ * (WinAnsi encoding).
7
+ *
8
+ * A single Type3 font supports up to 256 glyphs (single-byte encoding).
9
+ * When more than 256 distinct non-WinAnsi characters appear in a document,
10
+ * multiple Type3 fonts are created automatically.
11
+ *
12
+ * @see PDF Reference 1.7, §5.5.4 — Type 3 Fonts
13
+ */
14
+ import { PdfDict, pdfName, pdfRef, pdfNumber, pdfArray } from "../core/pdf-object.js";
15
+ import { PdfContentStream } from "../core/pdf-stream.js";
16
+ import { lookupGlyph, NOTDEF_GLYPH } from "./type3-glyphs.js";
17
+ // =============================================================================
18
+ // Constants
19
+ // =============================================================================
20
+ /**
21
+ * Type3 fonts use a FontMatrix to map glyph coordinates to text space.
22
+ * With a 1000-unit em square, FontMatrix = [0.001 0 0 0.001 0 0].
23
+ */
24
+ const UNITS_PER_EM = 1000;
25
+ /** Maximum glyphs per Type3 font (single-byte encoding limit). */
26
+ const MAX_GLYPHS_PER_FONT = 256;
27
+ // First usable encoding slot (0x00 = .notdef, start user glyphs at 0x01).
28
+ const FIRST_SLOT = 1;
29
+ /**
30
+ * Build and write Type3 fallback fonts to the PDF for the given code points.
31
+ *
32
+ * @param writer - The PdfWriter to add objects to.
33
+ * @param codePoints - Set of Unicode code points that need Type3 rendering.
34
+ * @param resourcePrefix - Prefix for resource names (e.g. "T3F").
35
+ * @returns Encoding and object info for use by FontManager.
36
+ */
37
+ export function writeType3Fonts(writer, codePoints, resourcePrefix = "T3F") {
38
+ const encoding = new Map();
39
+ const fontObjects = new Map();
40
+ const widths = new Map();
41
+ if (codePoints.size === 0) {
42
+ return { fontObjects, encoding, widths };
43
+ }
44
+ // Sort code points for deterministic output
45
+ const sorted = [...codePoints].sort((a, b) => a - b);
46
+ // Partition into chunks of MAX_GLYPHS_PER_FONT - 1 (slot 0 is .notdef)
47
+ const maxPerFont = MAX_GLYPHS_PER_FONT - FIRST_SLOT;
48
+ let fontIndex = 1;
49
+ for (let offset = 0; offset < sorted.length; offset += maxPerFont) {
50
+ const chunk = sorted.slice(offset, offset + maxPerFont);
51
+ const resourceName = `${resourcePrefix}${fontIndex}`;
52
+ fontIndex++;
53
+ const { objNum, fontWidths } = writeSingleType3Font(writer, chunk, resourceName);
54
+ fontObjects.set(resourceName, objNum);
55
+ widths.set(resourceName, fontWidths);
56
+ // Record encoding for each code point
57
+ for (let i = 0; i < chunk.length; i++) {
58
+ encoding.set(chunk[i], { resourceName, charCode: FIRST_SLOT + i });
59
+ }
60
+ }
61
+ return { fontObjects, encoding, widths };
62
+ }
63
+ // =============================================================================
64
+ // Internal — Single Type3 Font
65
+ // =============================================================================
66
+ function writeSingleType3Font(writer, codePoints, resourceName) {
67
+ // Build CharProcs: each glyph is a content stream
68
+ const charProcRefs = [];
69
+ const encodingNames = [];
70
+ const widthValues = new Array(FIRST_SLOT + codePoints.length).fill(0);
71
+ const fontWidths = new Map();
72
+ // Slot 0: .notdef
73
+ const notdefObj = writeGlyphStream(writer, NOTDEF_GLYPH);
74
+ charProcRefs.push({ name: ".notdef", objNum: notdefObj });
75
+ widthValues[0] = NOTDEF_GLYPH.width;
76
+ for (let i = 0; i < codePoints.length; i++) {
77
+ const cp = codePoints[i];
78
+ const glyphDef = lookupGlyph(cp) ?? NOTDEF_GLYPH;
79
+ const glyphName = `uni${cp.toString(16).toUpperCase().padStart(4, "0")}`;
80
+ const objNum = writeGlyphStream(writer, glyphDef);
81
+ charProcRefs.push({ name: glyphName, objNum });
82
+ encodingNames.push(glyphName);
83
+ const slot = FIRST_SLOT + i;
84
+ widthValues[slot] = glyphDef.width;
85
+ fontWidths.set(slot, glyphDef.width);
86
+ }
87
+ // Build CharProcs dictionary
88
+ const charProcsEntries = [];
89
+ for (const { name, objNum } of charProcRefs) {
90
+ charProcsEntries.push(`${pdfName(name)} ${pdfRef(objNum)}`);
91
+ }
92
+ const charProcsDict = `<<\n${charProcsEntries.join("\n")}\n>>`;
93
+ // Build Encoding dictionary
94
+ const differences = [];
95
+ differences.push(`${FIRST_SLOT}`);
96
+ for (const name of encodingNames) {
97
+ differences.push(pdfName(name));
98
+ }
99
+ const encodingObjNum = writer.allocObject();
100
+ const encodingDict = new PdfDict()
101
+ .set("Type", "/Encoding")
102
+ .set("Differences", `[${differences.join(" ")}]`);
103
+ writer.addObject(encodingObjNum, encodingDict);
104
+ // Build ToUnicode CMap
105
+ const toUnicodeObjNum = writeToUnicodeCMap(writer, codePoints);
106
+ // Build the Type3 font dictionary
107
+ const fontObjNum = writer.allocObject();
108
+ const fontBBox = `[0 0 ${UNITS_PER_EM} ${UNITS_PER_EM}]`;
109
+ const fontMatrix = "[0.001 0 0 0.001 0 0]";
110
+ const fontDict = new PdfDict()
111
+ .set("Type", "/Font")
112
+ .set("Subtype", "/Type3")
113
+ .set("Name", pdfName(resourceName))
114
+ .set("FontBBox", fontBBox)
115
+ .set("FontMatrix", fontMatrix)
116
+ .set("FirstChar", pdfNumber(0))
117
+ .set("LastChar", pdfNumber(widthValues.length - 1))
118
+ .set("Widths", pdfArray(widthValues.map(w => pdfNumber(w))))
119
+ .set("CharProcs", charProcsDict)
120
+ .set("Encoding", pdfRef(encodingObjNum))
121
+ .set("ToUnicode", pdfRef(toUnicodeObjNum));
122
+ writer.addObject(fontObjNum, fontDict);
123
+ return { objNum: fontObjNum, fontWidths };
124
+ }
125
+ // =============================================================================
126
+ // Glyph Stream Writer
127
+ // =============================================================================
128
+ function writeGlyphStream(writer, glyph) {
129
+ const stream = new PdfContentStream();
130
+ // d1 operator: wx wy llx lly urx ury — sets glyph width and bounding box
131
+ // This tells the PDF viewer the advance width and clip region
132
+ stream.raw(`${glyph.width} 0 0 0 ${UNITS_PER_EM} ${UNITS_PER_EM} d1`);
133
+ // Draw the glyph using the pen adapter
134
+ const pen = createPen(stream);
135
+ glyph.draw(pen);
136
+ const objNum = writer.allocObject();
137
+ writer.addStreamObject(objNum, new PdfDict(), stream);
138
+ return objNum;
139
+ }
140
+ /**
141
+ * Create a GlyphPen backed by a PdfContentStream.
142
+ */
143
+ function createPen(stream) {
144
+ return {
145
+ M: (x, y) => {
146
+ stream.moveTo(x, y);
147
+ },
148
+ L: (x, y) => {
149
+ stream.lineTo(x, y);
150
+ },
151
+ C: (x1, y1, x2, y2, x3, y3) => {
152
+ stream.curveTo(x1, y1, x2, y2, x3, y3);
153
+ },
154
+ Z: () => {
155
+ stream.closePath();
156
+ },
157
+ rect: (x, y, w, h) => {
158
+ stream.rect(x, y, w, h);
159
+ },
160
+ circle: (cx, cy, r) => {
161
+ stream.circle(cx, cy, r);
162
+ },
163
+ ellipse: (cx, cy, rx, ry) => {
164
+ stream.ellipse(cx, cy, rx, ry);
165
+ },
166
+ stroke: () => {
167
+ stream.stroke();
168
+ },
169
+ fill: () => {
170
+ stream.fill();
171
+ },
172
+ fillStroke: () => {
173
+ stream.fillAndStroke();
174
+ },
175
+ lineWidth: w => {
176
+ stream.setLineWidth(w);
177
+ }
178
+ };
179
+ }
180
+ // =============================================================================
181
+ // ToUnicode CMap
182
+ // =============================================================================
183
+ function writeToUnicodeCMap(writer, codePoints) {
184
+ const lines = [];
185
+ lines.push("/CIDInit /ProcSet findresource begin");
186
+ lines.push("12 dict begin");
187
+ lines.push("begincmap");
188
+ lines.push("/CIDSystemInfo");
189
+ lines.push("<< /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def");
190
+ lines.push("/CMapName /Adobe-Identity-UCS def");
191
+ lines.push("/CMapType 2 def");
192
+ lines.push("1 begincodespacerange");
193
+ lines.push("<00> <FF>");
194
+ lines.push("endcodespacerange");
195
+ // Write mappings in chunks of 100 (PDF limit per beginbfchar block)
196
+ for (let offset = 0; offset < codePoints.length; offset += 100) {
197
+ const chunk = codePoints.slice(offset, offset + 100);
198
+ lines.push(`${chunk.length} beginbfchar`);
199
+ for (let i = 0; i < chunk.length; i++) {
200
+ const slot = FIRST_SLOT + offset + i;
201
+ const cp = chunk[i];
202
+ const slotHex = slot.toString(16).toUpperCase().padStart(2, "0");
203
+ if (cp > 0xffff) {
204
+ // Supplementary character — encode as UTF-16 surrogate pair
205
+ const hi = Math.floor((cp - 0x10000) / 0x400) + 0xd800;
206
+ const lo = ((cp - 0x10000) % 0x400) + 0xdc00;
207
+ const hiHex = hi.toString(16).toUpperCase().padStart(4, "0");
208
+ const loHex = lo.toString(16).toUpperCase().padStart(4, "0");
209
+ lines.push(`<${slotHex}> <${hiHex}${loHex}>`);
210
+ }
211
+ else {
212
+ const cpHex = cp.toString(16).toUpperCase().padStart(4, "0");
213
+ lines.push(`<${slotHex}> <${cpHex}>`);
214
+ }
215
+ }
216
+ lines.push("endbfchar");
217
+ }
218
+ lines.push("endcmap");
219
+ lines.push("CMapName currentdict /CMap defineresource pop");
220
+ lines.push("end");
221
+ lines.push("end");
222
+ const cmapStr = lines.join("\n");
223
+ const encoder = new TextEncoder();
224
+ const data = encoder.encode(cmapStr);
225
+ const objNum = writer.allocObject();
226
+ writer.addStreamObject(objNum, new PdfDict(), data);
227
+ return objNum;
228
+ }