reamkit 0.1.0-alpha.0

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 (162) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/esm/bidi/algorithm.d.ts +9 -0
  4. package/dist/esm/bidi/algorithm.js +458 -0
  5. package/dist/esm/bidi/char-types.d.ts +2 -0
  6. package/dist/esm/bidi/char-types.js +439 -0
  7. package/dist/esm/bidi/index.d.ts +14 -0
  8. package/dist/esm/bidi/index.js +25 -0
  9. package/dist/esm/converter/docx-to-pdf.d.ts +15 -0
  10. package/dist/esm/converter/docx-to-pdf.js +227 -0
  11. package/dist/esm/converter/index.d.ts +4 -0
  12. package/dist/esm/converter/index.js +2 -0
  13. package/dist/esm/converter/xlsx-to-pdf.d.ts +13 -0
  14. package/dist/esm/converter/xlsx-to-pdf.js +515 -0
  15. package/dist/esm/crypto/asn1.d.ts +23 -0
  16. package/dist/esm/crypto/asn1.js +123 -0
  17. package/dist/esm/crypto/cms.d.ts +9 -0
  18. package/dist/esm/crypto/cms.js +34 -0
  19. package/dist/esm/crypto/index.d.ts +2 -0
  20. package/dist/esm/crypto/index.js +1 -0
  21. package/dist/esm/document-model/index.d.ts +1 -0
  22. package/dist/esm/document-model/index.js +0 -0
  23. package/dist/esm/document-model/types.d.ts +403 -0
  24. package/dist/esm/font/arabic-joining.d.ts +4 -0
  25. package/dist/esm/font/arabic-joining.js +97 -0
  26. package/dist/esm/font/binary-reader.d.ts +13 -0
  27. package/dist/esm/font/binary-reader.js +44 -0
  28. package/dist/esm/font/font-registry.d.ts +19 -0
  29. package/dist/esm/font/font-registry.js +39 -0
  30. package/dist/esm/font/index.d.ts +7 -0
  31. package/dist/esm/font/opentype-layout.d.ts +21 -0
  32. package/dist/esm/font/opentype-layout.js +329 -0
  33. package/dist/esm/font/ttf-parser.d.ts +29 -0
  34. package/dist/esm/font/ttf-parser.js +290 -0
  35. package/dist/esm/font/ttf-subset.d.ts +3 -0
  36. package/dist/esm/font/ttf-subset.js +201 -0
  37. package/dist/esm/fonts/index.d.ts +2 -0
  38. package/dist/esm/fonts/remote-fonts.d.ts +13 -0
  39. package/dist/esm/fonts/remote-fonts.js +94 -0
  40. package/dist/esm/hyphenation/index.d.ts +10 -0
  41. package/dist/esm/hyphenation/index.js +38 -0
  42. package/dist/esm/hyphenation/liang.d.ts +10 -0
  43. package/dist/esm/hyphenation/liang.js +79 -0
  44. package/dist/esm/hyphenation/patterns-en-us.d.ts +2 -0
  45. package/dist/esm/hyphenation/patterns-en-us.js +5 -0
  46. package/dist/esm/hyphenation/patterns-ru.d.ts +2 -0
  47. package/dist/esm/hyphenation/patterns-ru.js +5 -0
  48. package/dist/esm/index.d.ts +12 -0
  49. package/dist/esm/index.js +13 -0
  50. package/dist/esm/line-breaker/index.d.ts +2 -0
  51. package/dist/esm/line-breaker/knuth-plass.d.ts +30 -0
  52. package/dist/esm/line-breaker/knuth-plass.js +172 -0
  53. package/dist/esm/numbering/index.d.ts +1 -0
  54. package/dist/esm/numbering/state.d.ts +6 -0
  55. package/dist/esm/numbering/state.js +83 -0
  56. package/dist/esm/ooxml/drawingml/chart-parser.d.ts +3 -0
  57. package/dist/esm/ooxml/drawingml/chart-parser.js +218 -0
  58. package/dist/esm/ooxml/drawingml/colors.d.ts +17 -0
  59. package/dist/esm/ooxml/drawingml/colors.js +125 -0
  60. package/dist/esm/ooxml/drawingml/theme-parser.d.ts +1 -0
  61. package/dist/esm/ooxml/drawingml/theme-parser.js +55 -0
  62. package/dist/esm/ooxml/index.d.ts +1 -0
  63. package/dist/esm/ooxml/math/omml-parser.d.ts +4 -0
  64. package/dist/esm/ooxml/math/omml-parser.js +217 -0
  65. package/dist/esm/ooxml/spreadsheet/cell-reference.d.ts +6 -0
  66. package/dist/esm/ooxml/spreadsheet/cell-reference.js +26 -0
  67. package/dist/esm/ooxml/spreadsheet/defined-name-ref.d.ts +11 -0
  68. package/dist/esm/ooxml/spreadsheet/defined-name-ref.js +64 -0
  69. package/dist/esm/ooxml/spreadsheet/index.d.ts +12 -0
  70. package/dist/esm/ooxml/spreadsheet/index.js +7 -0
  71. package/dist/esm/ooxml/spreadsheet/number-format.d.ts +1 -0
  72. package/dist/esm/ooxml/spreadsheet/number-format.js +438 -0
  73. package/dist/esm/ooxml/spreadsheet/shared-strings-parser.d.ts +1 -0
  74. package/dist/esm/ooxml/spreadsheet/shared-strings-parser.js +47 -0
  75. package/dist/esm/ooxml/spreadsheet/styles-parser.d.ts +52 -0
  76. package/dist/esm/ooxml/spreadsheet/styles-parser.js +225 -0
  77. package/dist/esm/ooxml/spreadsheet/workbook-parser.d.ts +16 -0
  78. package/dist/esm/ooxml/spreadsheet/workbook-parser.js +90 -0
  79. package/dist/esm/ooxml/spreadsheet/worksheet-parser.d.ts +60 -0
  80. package/dist/esm/ooxml/spreadsheet/worksheet-parser.js +311 -0
  81. package/dist/esm/ooxml/wordproc/document-parser.d.ts +9 -0
  82. package/dist/esm/ooxml/wordproc/document-parser.js +274 -0
  83. package/dist/esm/ooxml/wordproc/drawing-parser.d.ts +33 -0
  84. package/dist/esm/ooxml/wordproc/drawing-parser.js +374 -0
  85. package/dist/esm/ooxml/wordproc/font-table.d.ts +15 -0
  86. package/dist/esm/ooxml/wordproc/font-table.js +82 -0
  87. package/dist/esm/ooxml/wordproc/index.d.ts +10 -0
  88. package/dist/esm/ooxml/wordproc/index.js +9 -0
  89. package/dist/esm/ooxml/wordproc/numbering-parser.d.ts +3 -0
  90. package/dist/esm/ooxml/wordproc/numbering-parser.js +89 -0
  91. package/dist/esm/ooxml/wordproc/paragraph-properties.d.ts +2 -0
  92. package/dist/esm/ooxml/wordproc/paragraph-properties.js +85 -0
  93. package/dist/esm/ooxml/wordproc/po-helpers.d.ts +14 -0
  94. package/dist/esm/ooxml/wordproc/po-helpers.js +76 -0
  95. package/dist/esm/ooxml/wordproc/po-to-flat.d.ts +2 -0
  96. package/dist/esm/ooxml/wordproc/po-to-flat.js +28 -0
  97. package/dist/esm/ooxml/wordproc/run-properties.d.ts +2 -0
  98. package/dist/esm/ooxml/wordproc/run-properties.js +82 -0
  99. package/dist/esm/ooxml/wordproc/settings-parser.d.ts +5 -0
  100. package/dist/esm/ooxml/wordproc/settings-parser.js +26 -0
  101. package/dist/esm/ooxml/wordproc/styles-parser.d.ts +3 -0
  102. package/dist/esm/ooxml/wordproc/styles-parser.js +67 -0
  103. package/dist/esm/ooxml/wordproc/table-parser.d.ts +3 -0
  104. package/dist/esm/ooxml/wordproc/table-parser.js +162 -0
  105. package/dist/esm/ooxml/wordproc/text-extractor.d.ts +1 -0
  106. package/dist/esm/ooxml/wordproc/text-extractor.js +1 -0
  107. package/dist/esm/ooxml/wordproc/xml-helpers.d.ts +9 -0
  108. package/dist/esm/ooxml/wordproc/xml-helpers.js +36 -0
  109. package/dist/esm/opc/core-properties.d.ts +11 -0
  110. package/dist/esm/opc/core-properties.js +51 -0
  111. package/dist/esm/opc/index.d.ts +5 -0
  112. package/dist/esm/opc/index.js +3 -0
  113. package/dist/esm/opc/package.d.ts +26 -0
  114. package/dist/esm/opc/package.js +113 -0
  115. package/dist/esm/opc/relationship-types.d.ts +3 -0
  116. package/dist/esm/opc/relationship-types.js +4 -0
  117. package/dist/esm/opc/relationships.d.ts +7 -0
  118. package/dist/esm/opc/relationships.js +28 -0
  119. package/dist/esm/pdf/arc-to-bezier.d.ts +5 -0
  120. package/dist/esm/pdf/arc-to-bezier.js +58 -0
  121. package/dist/esm/pdf/builtin-fonts.d.ts +2 -0
  122. package/dist/esm/pdf/chart-geometry.d.ts +64 -0
  123. package/dist/esm/pdf/chart-geometry.js +674 -0
  124. package/dist/esm/pdf/cid-font.d.ts +15 -0
  125. package/dist/esm/pdf/cid-font.js +174 -0
  126. package/dist/esm/pdf/embedded-file.d.ts +11 -0
  127. package/dist/esm/pdf/embedded-file.js +23 -0
  128. package/dist/esm/pdf/icc-profile.d.ts +1 -0
  129. package/dist/esm/pdf/icc-profile.js +166 -0
  130. package/dist/esm/pdf/image-xobject.d.ts +13 -0
  131. package/dist/esm/pdf/image-xobject.js +335 -0
  132. package/dist/esm/pdf/index.d.ts +11 -0
  133. package/dist/esm/pdf/index.js +5 -0
  134. package/dist/esm/pdf/math-layout.d.ts +45 -0
  135. package/dist/esm/pdf/math-layout.js +1138 -0
  136. package/dist/esm/pdf/objects.d.ts +32 -0
  137. package/dist/esm/pdf/objects.js +54 -0
  138. package/dist/esm/pdf/preset-geometry.d.ts +6 -0
  139. package/dist/esm/pdf/preset-geometry.js +199 -0
  140. package/dist/esm/pdf/serialize.d.ts +3 -0
  141. package/dist/esm/pdf/serialize.js +54 -0
  142. package/dist/esm/pdf/signature.d.ts +25 -0
  143. package/dist/esm/pdf/signature.js +126 -0
  144. package/dist/esm/pdf/struct-tree.d.ts +31 -0
  145. package/dist/esm/pdf/struct-tree.js +109 -0
  146. package/dist/esm/pdf/styled-page-renderer.d.ts +43 -0
  147. package/dist/esm/pdf/styled-page-renderer.js +2317 -0
  148. package/dist/esm/pdf/text-encoding.d.ts +2 -0
  149. package/dist/esm/pdf/text-page-renderer.d.ts +16 -0
  150. package/dist/esm/pdf/text-page-renderer.js +4 -0
  151. package/dist/esm/pdf/vector-graphics.d.ts +46 -0
  152. package/dist/esm/pdf/vector-graphics.js +103 -0
  153. package/dist/esm/pdf/writer.d.ts +10 -0
  154. package/dist/esm/pdf/writer.js +81 -0
  155. package/dist/esm/pdf/xmp.d.ts +13 -0
  156. package/dist/esm/pdf/xmp.js +38 -0
  157. package/dist/esm/style-cascade/index.d.ts +3 -0
  158. package/dist/esm/style-cascade/resolver.d.ts +4 -0
  159. package/dist/esm/style-cascade/resolver.js +96 -0
  160. package/dist/esm/style-cascade/types.d.ts +29 -0
  161. package/dist/esm/style-cascade/types.js +26 -0
  162. package/package.json +90 -0
@@ -0,0 +1,674 @@
1
+ var AXIS_COLOR = "595959";
2
+ var GRID_COLOR = "D9D9D9";
3
+ var LABEL_COLOR = "595959";
4
+ var TITLE_COLOR = "404040";
5
+ var SERIES_COLORS = [
6
+ "4472C4",
7
+ "ED7D31",
8
+ "A5A5A5",
9
+ "FFC000",
10
+ "5B9BD5",
11
+ "70AD47"
12
+ ];
13
+ var seriesColor = (s, i) => s.colorHex ?? SERIES_COLORS[i % SERIES_COLORS.length];
14
+ function niceNum(range, round) {
15
+ const exp = Math.floor(Math.log10(range));
16
+ const f = range / 10 ** exp;
17
+ let nf;
18
+ if (round) nf = f < 1.5 ? 1 : f < 3 ? 2 : f < 7 ? 5 : 10;
19
+ else nf = f <= 1 ? 1 : f <= 2 ? 2 : f <= 5 ? 5 : 10;
20
+ return nf * 10 ** exp;
21
+ }
22
+ function niceScale(dataMin, dataMax, maxTicks = 6) {
23
+ const lo = Math.min(dataMin, dataMax);
24
+ let hi = Math.max(dataMin, dataMax);
25
+ if (lo === hi) hi = lo + 1;
26
+ const step = niceNum(niceNum(hi - lo, false) / Math.max(1, maxTicks - 1), true);
27
+ return {
28
+ min: Math.floor(lo / step) * step,
29
+ max: Math.ceil(hi / step) * step,
30
+ step
31
+ };
32
+ }
33
+ function formatTick(v, step) {
34
+ if (Number.isInteger(step) && Number.isInteger(v)) return String(v);
35
+ const decimals = Math.max(0, -Math.floor(Math.log10(step)));
36
+ return v.toFixed(decimals).replace(/\.?0+$/, (m) => m.includes(".") ? "" : m);
37
+ }
38
+ var ticks = (s) => {
39
+ const out = [];
40
+ for (let v = s.min; v <= s.max + 1e-9; v += s.step) out.push(Math.abs(v) < 1e-9 ? 0 : v);
41
+ return out;
42
+ };
43
+ function buildFrame(chart, wPt, hPt, measure, horizontal, opts = {}) {
44
+ const rects = [];
45
+ const polylines = [];
46
+ const labels = [];
47
+ const nCats = Math.max(chart.categories.length, ...chart.series.map((s) => s.values.length), 1);
48
+ const allVals = chart.series.flatMap((s) => s.values.slice(0, nCats));
49
+ const [dataMin, dataMax] = opts.dataRange ?? [Math.min(0, ...allVals), Math.max(0, ...allVals)];
50
+ const scale = niceScale(dataMin, dataMax);
51
+ const fmtVal = opts.formatValue ?? ((v) => formatTick(v, scale.step));
52
+ const tickVals = ticks(scale);
53
+ let top = 4;
54
+ if (chart.title) top += 13 * 1.6;
55
+ if (chart.valAxisTitle) top += 9 * 1.4;
56
+ const legend = layoutLegend(chart.series.map((s, i) => ({
57
+ name: s.name ?? "",
58
+ colorHex: seriesColor(s, i)
59
+ })).filter((e) => e.name !== ""), chart.hasLegend, chart.legendPos ?? "b", wPt, hPt, measure);
60
+ const plotRight = wPt - 4 - legend.rightWidth;
61
+ const tickLabelW = Math.max(0, ...tickVals.map((v) => measure(fmtVal(v), 9))) + 4;
62
+ const catLabelH = 9 * 1.6;
63
+ const catTitleH = chart.catAxisTitle ? 9 * 1.5 : 0;
64
+ const x0 = 4 + tickLabelW;
65
+ const y0 = 4 + legend.bottomHeight + catTitleH + catLabelH;
66
+ const plotW = Math.max(1, plotRight - x0);
67
+ const plotH = Math.max(1, hPt - top - y0);
68
+ const valueOffset = (v) => (v - scale.min) / (scale.max - scale.min) * (horizontal ? plotW : plotH);
69
+ const zeroOffset = valueOffset(0);
70
+ if (chart.title) labels.push({
71
+ text: chart.title,
72
+ x: wPt / 2,
73
+ y: hPt - 4 - 13,
74
+ sizePt: 13,
75
+ colorHex: TITLE_COLOR,
76
+ align: "center"
77
+ });
78
+ if (chart.valAxisTitle) labels.push({
79
+ text: chart.valAxisTitle,
80
+ x: x0,
81
+ y: hPt - top + 3,
82
+ sizePt: 9,
83
+ colorHex: LABEL_COLOR,
84
+ align: "left"
85
+ });
86
+ if (chart.catAxisTitle) labels.push({
87
+ text: chart.catAxisTitle,
88
+ x: x0 + plotW / 2,
89
+ y: legend.bottomHeight + 2,
90
+ sizePt: 9,
91
+ colorHex: LABEL_COLOR,
92
+ align: "center"
93
+ });
94
+ for (const v of tickVals) {
95
+ const off = valueOffset(v);
96
+ if (horizontal) {
97
+ const gx = x0 + off;
98
+ polylines.push({
99
+ points: [[gx, y0], [gx, y0 + plotH]],
100
+ strokeHex: GRID_COLOR,
101
+ widthPt: .75
102
+ });
103
+ labels.push({
104
+ text: fmtVal(v),
105
+ x: gx,
106
+ y: y0 - 9,
107
+ sizePt: 9,
108
+ colorHex: LABEL_COLOR,
109
+ align: "center"
110
+ });
111
+ } else {
112
+ const gy = y0 + off;
113
+ polylines.push({
114
+ points: [[x0, gy], [x0 + plotW, gy]],
115
+ strokeHex: GRID_COLOR,
116
+ widthPt: .75
117
+ });
118
+ labels.push({
119
+ text: fmtVal(v),
120
+ x: x0 - 3,
121
+ y: gy - 9 / 3,
122
+ sizePt: 9,
123
+ colorHex: LABEL_COLOR,
124
+ align: "right"
125
+ });
126
+ }
127
+ }
128
+ const slot = (horizontal ? plotH : plotW) / nCats;
129
+ for (let c = 0; c < nCats; c++) {
130
+ const cat = chart.categories[c] ?? "";
131
+ if (!cat) continue;
132
+ const center = (horizontal ? y0 : x0) + c * slot + slot / 2;
133
+ if (horizontal) labels.push({
134
+ text: cat,
135
+ x: x0 - 3,
136
+ y: center - 9 / 3,
137
+ sizePt: 9,
138
+ colorHex: LABEL_COLOR,
139
+ align: "right"
140
+ });
141
+ else labels.push({
142
+ text: cat,
143
+ x: center,
144
+ y: y0 - 9,
145
+ sizePt: 9,
146
+ colorHex: LABEL_COLOR,
147
+ align: "center"
148
+ });
149
+ }
150
+ polylines.push({
151
+ points: [[x0, y0], [x0, y0 + plotH]],
152
+ strokeHex: AXIS_COLOR,
153
+ widthPt: 1
154
+ });
155
+ polylines.push({
156
+ points: [[x0, y0], [x0 + plotW, y0]],
157
+ strokeHex: AXIS_COLOR,
158
+ widthPt: 1
159
+ });
160
+ legend.emit(rects, labels);
161
+ return {
162
+ x0,
163
+ y0,
164
+ plotW,
165
+ plotH,
166
+ nCats,
167
+ slot,
168
+ horizontal,
169
+ zeroOffset,
170
+ valueOffset,
171
+ rects,
172
+ polylines,
173
+ labels
174
+ };
175
+ }
176
+ var pctLabel = (v) => `${Math.round(v * 100)}%`;
177
+ var fmtDataLabel = (v) => Number.isInteger(v) ? String(v) : String(Math.round(v * 100) / 100);
178
+ function catCount(chart) {
179
+ return Math.max(chart.categories.length, ...chart.series.map((s) => s.values.length), 1);
180
+ }
181
+ function stackedTotals(chart, nCats) {
182
+ let max = 0;
183
+ let min = 0;
184
+ for (let c = 0; c < nCats; c++) {
185
+ let pos = 0;
186
+ let neg = 0;
187
+ for (const s of chart.series) {
188
+ const v = s.values[c] ?? 0;
189
+ if (v >= 0) pos += v;
190
+ else neg += v;
191
+ }
192
+ max = Math.max(max, pos);
193
+ min = Math.min(min, neg);
194
+ }
195
+ return {
196
+ min,
197
+ max
198
+ };
199
+ }
200
+ function groupingFrameOpts(chart, nCats) {
201
+ const g = chart.grouping ?? "clustered";
202
+ if (g === "percentStacked") return {
203
+ dataRange: [0, 1],
204
+ formatValue: pctLabel
205
+ };
206
+ if (g === "stacked") {
207
+ const t = stackedTotals(chart, nCats);
208
+ return { dataRange: [Math.min(0, t.min), Math.max(0, t.max)] };
209
+ }
210
+ return {};
211
+ }
212
+ function buildBarScene(chart, wPt, hPt, measure) {
213
+ const g = chart.grouping ?? "clustered";
214
+ const stacked = g === "stacked" || g === "percentStacked";
215
+ const percent = g === "percentStacked";
216
+ const horizontal = chart.barDir === "bar";
217
+ const f = buildFrame(chart, wPt, hPt, measure, horizontal, groupingFrameOpts(chart, catCount(chart)));
218
+ if (stacked) {
219
+ const groupPad = f.slot * .15;
220
+ const barW = f.slot - 2 * groupPad;
221
+ for (let c = 0; c < f.nCats; c++) {
222
+ const along = (horizontal ? f.y0 : f.x0) + c * f.slot + groupPad;
223
+ const denom = percent ? chart.series.reduce((a, s) => a + Math.abs(s.values[c] ?? 0), 0) || 1 : 1;
224
+ let cumPos = 0;
225
+ let cumNeg = 0;
226
+ for (let s = 0; s < chart.series.length; s++) {
227
+ const series = chart.series[s];
228
+ const v = (series.values[c] ?? 0) / denom;
229
+ const base = v >= 0 ? cumPos : cumNeg;
230
+ const top = base + v;
231
+ const o0 = f.valueOffset(base);
232
+ const o1 = f.valueOffset(top);
233
+ const lo = Math.min(o0, o1);
234
+ const span = Math.abs(o1 - o0);
235
+ const color = pointColor(series, c) ?? seriesColor(series, s);
236
+ if (horizontal) f.rects.push({
237
+ x: f.x0 + lo,
238
+ y: along,
239
+ w: span,
240
+ h: barW,
241
+ fillHex: color
242
+ });
243
+ else f.rects.push({
244
+ x: along,
245
+ y: f.y0 + lo,
246
+ w: barW,
247
+ h: span,
248
+ fillHex: color
249
+ });
250
+ if (chart.showValues && span > 9) {
251
+ const raw = series.values[c] ?? 0;
252
+ if (horizontal) f.labels.push(centeredLabel(fmtDataLabel(raw), f.x0 + lo + span / 2, along + barW * .3));
253
+ else f.labels.push(centeredLabel(fmtDataLabel(raw), along + barW / 2, f.y0 + lo + span / 2 - 3));
254
+ }
255
+ if (v >= 0) cumPos = top;
256
+ else cumNeg = top;
257
+ }
258
+ }
259
+ return {
260
+ rects: f.rects,
261
+ polylines: f.polylines,
262
+ wedges: [],
263
+ labels: f.labels
264
+ };
265
+ }
266
+ const nSer = Math.max(1, chart.series.length);
267
+ const groupPad = f.slot * .15;
268
+ const barW = (f.slot - 2 * groupPad) / nSer;
269
+ for (let c = 0; c < f.nCats; c++) {
270
+ const slotStart = (horizontal ? f.y0 : f.x0) + c * f.slot + groupPad;
271
+ for (let s = 0; s < chart.series.length; s++) {
272
+ const series = chart.series[s];
273
+ const len = f.valueOffset(series.values[c] ?? 0) - f.zeroOffset;
274
+ const color = pointColor(series, c) ?? seriesColor(series, s);
275
+ const along = slotStart + s * barW;
276
+ if (horizontal) {
277
+ const bx = f.x0 + f.zeroOffset + Math.min(0, len);
278
+ f.rects.push({
279
+ x: bx,
280
+ y: along,
281
+ w: Math.abs(len),
282
+ h: barW * .9,
283
+ fillHex: color
284
+ });
285
+ } else {
286
+ const by = f.y0 + f.zeroOffset + Math.min(0, len);
287
+ f.rects.push({
288
+ x: along,
289
+ y: by,
290
+ w: barW * .9,
291
+ h: Math.abs(len),
292
+ fillHex: color
293
+ });
294
+ }
295
+ if (chart.showValues) {
296
+ const txt = fmtDataLabel(series.values[c] ?? 0);
297
+ if (horizontal) {
298
+ const end = f.x0 + f.zeroOffset + len;
299
+ f.labels.push({
300
+ text: txt,
301
+ x: end + (len >= 0 ? 3 : -3),
302
+ y: along + barW * .25,
303
+ sizePt: 9,
304
+ colorHex: LABEL_COLOR,
305
+ align: len >= 0 ? "left" : "right"
306
+ });
307
+ } else {
308
+ const end = f.y0 + f.zeroOffset + len;
309
+ f.labels.push(centeredLabel(txt, along + barW * .45, len >= 0 ? end + 2 : end - 9));
310
+ }
311
+ }
312
+ }
313
+ }
314
+ return {
315
+ rects: f.rects,
316
+ polylines: f.polylines,
317
+ wedges: [],
318
+ labels: f.labels
319
+ };
320
+ }
321
+ function centeredLabel(text, x, y) {
322
+ return {
323
+ text,
324
+ x,
325
+ y,
326
+ sizePt: 9,
327
+ colorHex: LABEL_COLOR,
328
+ align: "center"
329
+ };
330
+ }
331
+ function areaBand(top, base, f, xAt, fillHex) {
332
+ const pts = [];
333
+ for (let c = 0; c < f.nCats; c++) pts.push([xAt(c), f.y0 + f.valueOffset(top[c] ?? 0)]);
334
+ for (let c = f.nCats - 1; c >= 0; c--) pts.push([xAt(c), f.y0 + f.valueOffset(base[c] ?? 0)]);
335
+ return {
336
+ points: pts,
337
+ fillHex,
338
+ strokeHex: fillHex,
339
+ widthPt: 1
340
+ };
341
+ }
342
+ function buildAreaScene(chart, wPt, hPt, measure) {
343
+ const g = chart.grouping ?? "standard";
344
+ const stacked = g === "stacked" || g === "percentStacked";
345
+ const percent = g === "percentStacked";
346
+ const nCats = catCount(chart);
347
+ const f = buildFrame(chart, wPt, hPt, measure, false, groupingFrameOpts(chart, nCats));
348
+ const xAt = (c) => f.x0 + c * f.slot + f.slot / 2;
349
+ const polygons = [];
350
+ if (stacked) {
351
+ const cum = new Array(nCats).fill(0);
352
+ for (let s = 0; s < chart.series.length; s++) {
353
+ const series = chart.series[s];
354
+ const base = cum.slice();
355
+ const top = cum.map((b, c) => {
356
+ const denom = percent ? chart.series.reduce((a, ss) => a + Math.abs(ss.values[c] ?? 0), 0) || 1 : 1;
357
+ return b + (series.values[c] ?? 0) / denom;
358
+ });
359
+ polygons.push(areaBand(top, base, f, xAt, seriesColor(series, s)));
360
+ for (let c = 0; c < nCats; c++) cum[c] = top[c];
361
+ }
362
+ } else {
363
+ const base = new Array(nCats).fill(0);
364
+ for (let s = chart.series.length - 1; s >= 0; s--) {
365
+ const series = chart.series[s];
366
+ const top = Array.from({ length: nCats }, (_, c) => series.values[c] ?? 0);
367
+ polygons.push(areaBand(top, base, f, xAt, seriesColor(series, s)));
368
+ }
369
+ }
370
+ return {
371
+ rects: f.rects,
372
+ polylines: f.polylines,
373
+ wedges: [],
374
+ labels: f.labels,
375
+ polygons
376
+ };
377
+ }
378
+ function buildScatterScene(chart, wPt, hPt, measure) {
379
+ const rects = [];
380
+ const polylines = [];
381
+ const labels = [];
382
+ const xs = [];
383
+ const ys = [];
384
+ for (const s of chart.series) for (let i = 0; i < s.values.length; i++) {
385
+ xs.push(s.xValues?.[i] ?? i);
386
+ ys.push(s.values[i] ?? 0);
387
+ }
388
+ if (xs.length === 0) return {
389
+ rects,
390
+ polylines,
391
+ wedges: [],
392
+ labels
393
+ };
394
+ const xScale = niceScale(Math.min(...xs), Math.max(...xs));
395
+ const yScale = niceScale(Math.min(...ys), Math.max(...ys));
396
+ const xTicks = ticks(xScale);
397
+ const yTicks = ticks(yScale);
398
+ let top = 4;
399
+ if (chart.title) top += 13 * 1.6;
400
+ const legend = layoutLegend(chart.series.map((s, i) => ({
401
+ name: s.name ?? "",
402
+ colorHex: seriesColor(s, i)
403
+ })).filter((e) => e.name !== ""), chart.hasLegend, chart.legendPos ?? "b", wPt, hPt, measure);
404
+ const x0 = 4 + (Math.max(0, ...yTicks.map((v) => measure(formatTick(v, yScale.step), 9))) + 4);
405
+ const y0 = 4 + legend.bottomHeight + 9 * 1.6;
406
+ const plotW = Math.max(1, wPt - 4 - legend.rightWidth - x0);
407
+ const plotH = Math.max(1, hPt - top - y0);
408
+ const xAt = (v) => x0 + (v - xScale.min) / (xScale.max - xScale.min) * plotW;
409
+ const yAt = (v) => y0 + (v - yScale.min) / (yScale.max - yScale.min) * plotH;
410
+ if (chart.title) labels.push({
411
+ text: chart.title,
412
+ x: wPt / 2,
413
+ y: hPt - 4 - 13,
414
+ sizePt: 13,
415
+ colorHex: TITLE_COLOR,
416
+ align: "center"
417
+ });
418
+ for (const v of yTicks) {
419
+ const gy = yAt(v);
420
+ polylines.push({
421
+ points: [[x0, gy], [x0 + plotW, gy]],
422
+ strokeHex: GRID_COLOR,
423
+ widthPt: .75
424
+ });
425
+ labels.push({
426
+ text: formatTick(v, yScale.step),
427
+ x: x0 - 3,
428
+ y: gy - 9 / 3,
429
+ sizePt: 9,
430
+ colorHex: LABEL_COLOR,
431
+ align: "right"
432
+ });
433
+ }
434
+ for (const v of xTicks) {
435
+ const gx = xAt(v);
436
+ polylines.push({
437
+ points: [[gx, y0], [gx, y0 + plotH]],
438
+ strokeHex: GRID_COLOR,
439
+ widthPt: .75
440
+ });
441
+ labels.push({
442
+ text: formatTick(v, xScale.step),
443
+ x: gx,
444
+ y: y0 - 9,
445
+ sizePt: 9,
446
+ colorHex: LABEL_COLOR,
447
+ align: "center"
448
+ });
449
+ }
450
+ polylines.push({
451
+ points: [[x0, y0], [x0, y0 + plotH]],
452
+ strokeHex: AXIS_COLOR,
453
+ widthPt: 1
454
+ });
455
+ polylines.push({
456
+ points: [[x0, y0], [x0 + plotW, y0]],
457
+ strokeHex: AXIS_COLOR,
458
+ widthPt: 1
459
+ });
460
+ for (let s = 0; s < chart.series.length; s++) {
461
+ const series = chart.series[s];
462
+ const color = seriesColor(series, s);
463
+ for (let i = 0; i < series.values.length; i++) {
464
+ const px = xAt(series.xValues?.[i] ?? i);
465
+ const py = yAt(series.values[i] ?? 0);
466
+ rects.push({
467
+ x: px - 2,
468
+ y: py - 2,
469
+ w: 4,
470
+ h: 4,
471
+ fillHex: color
472
+ });
473
+ }
474
+ }
475
+ legend.emit(rects, labels);
476
+ return {
477
+ rects,
478
+ polylines,
479
+ wedges: [],
480
+ labels
481
+ };
482
+ }
483
+ function buildLineScene(chart, wPt, hPt, measure) {
484
+ const allVals = chart.series.flatMap((s) => s.values);
485
+ const f = buildFrame(chart, wPt, hPt, measure, false, { dataRange: allVals.length > 0 ? [Math.min(...allVals), Math.max(...allVals)] : [0, 1] });
486
+ for (let s = 0; s < chart.series.length; s++) {
487
+ const series = chart.series[s];
488
+ const color = seriesColor(series, s);
489
+ const pts = [];
490
+ for (let c = 0; c < f.nCats; c++) {
491
+ const x = f.x0 + c * f.slot + f.slot / 2;
492
+ const y = f.y0 + f.valueOffset(series.values[c] ?? 0);
493
+ pts.push([x, y]);
494
+ if (chart.showValues) f.labels.push(centeredLabel(fmtDataLabel(series.values[c] ?? 0), x, y + 3));
495
+ }
496
+ if (pts.length >= 2) f.polylines.push({
497
+ points: pts,
498
+ strokeHex: color,
499
+ widthPt: 1.5
500
+ });
501
+ else if (pts.length === 1) {
502
+ const [px, py] = pts[0];
503
+ f.rects.push({
504
+ x: px - 1.5,
505
+ y: py - 1.5,
506
+ w: 3,
507
+ h: 3,
508
+ fillHex: color
509
+ });
510
+ }
511
+ }
512
+ return {
513
+ rects: f.rects,
514
+ polylines: f.polylines,
515
+ wedges: [],
516
+ labels: f.labels
517
+ };
518
+ }
519
+ var sliceColor = (series, i) => pointColor(series, i) ?? SERIES_COLORS[i % SERIES_COLORS.length];
520
+ function buildPieScene(chart, wPt, hPt, measure) {
521
+ const rects = [];
522
+ const wedges = [];
523
+ const labels = [];
524
+ const series = chart.series[0];
525
+ const values = series ? series.values.map((v) => Math.max(0, v)) : [];
526
+ const total = values.reduce((a, b) => a + b, 0);
527
+ if (!series || total <= 0) return {
528
+ rects,
529
+ polylines: [],
530
+ wedges,
531
+ labels
532
+ };
533
+ let top = 4;
534
+ if (chart.title) top += 13 * 1.6;
535
+ const legend = layoutLegend(chart.categories.map((c, i) => ({
536
+ name: c,
537
+ colorHex: sliceColor(series, i)
538
+ })), chart.hasLegend, chart.legendPos ?? "r", wPt, hPt, measure);
539
+ const availW = Math.max(1, wPt - 8 - legend.rightWidth);
540
+ const availH = Math.max(1, hPt - top - 4 - legend.bottomHeight);
541
+ const r = Math.max(1, Math.min(availW, availH) / 2 * .95);
542
+ const cx = 4 + availW / 2;
543
+ const cy = 4 + legend.bottomHeight + availH / 2;
544
+ const holeR = chart.doughnut ? r * .5 : 0;
545
+ const labelR = chart.doughnut ? (holeR + r) / 2 : r * .6;
546
+ let ang = Math.PI / 2;
547
+ for (let i = 0; i < values.length; i++) {
548
+ const v = values[i];
549
+ if (v <= 0) continue;
550
+ const sweep = -(v / total) * 2 * Math.PI;
551
+ wedges.push({
552
+ cx,
553
+ cy,
554
+ r,
555
+ startRad: ang,
556
+ sweepRad: sweep,
557
+ fillHex: sliceColor(series, i),
558
+ strokeHex: "FFFFFF"
559
+ });
560
+ const mid = ang + sweep / 2;
561
+ const pct = Math.round(v / total * 100);
562
+ if (pct >= 5) labels.push({
563
+ text: `${pct}%`,
564
+ x: cx + Math.cos(mid) * labelR,
565
+ y: cy + Math.sin(mid) * labelR - 9 / 3,
566
+ sizePt: 9,
567
+ colorHex: chart.doughnut ? LABEL_COLOR : "FFFFFF",
568
+ align: "center"
569
+ });
570
+ ang += sweep;
571
+ }
572
+ if (holeR > 0) wedges.push({
573
+ cx,
574
+ cy,
575
+ r: holeR,
576
+ startRad: 0,
577
+ sweepRad: -2 * Math.PI,
578
+ fillHex: "FFFFFF"
579
+ });
580
+ if (chart.title) labels.push({
581
+ text: chart.title,
582
+ x: wPt / 2,
583
+ y: hPt - 4 - 13,
584
+ sizePt: 13,
585
+ colorHex: TITLE_COLOR,
586
+ align: "center"
587
+ });
588
+ legend.emit(rects, labels);
589
+ return {
590
+ rects,
591
+ polylines: [],
592
+ wedges,
593
+ labels
594
+ };
595
+ }
596
+ function pointColor(series, idx) {
597
+ return series.pointColors?.find((p) => p.idx === idx)?.colorHex;
598
+ }
599
+ function layoutLegend(entries, hasLegend, pos, wPt, hPt, measure) {
600
+ if (!hasLegend || entries.length === 0) return {
601
+ rightWidth: 0,
602
+ bottomHeight: 0,
603
+ emit: () => {}
604
+ };
605
+ const sw = 9;
606
+ const gap = 4;
607
+ const entryW = (e) => sw + 3 + measure(e.name, 9) + gap * 2;
608
+ if (pos === "r" || pos === "l") {
609
+ const colW = Math.max(...entries.map(entryW));
610
+ return {
611
+ rightWidth: pos === "r" ? colW : 0,
612
+ bottomHeight: 0,
613
+ emit: (rects, labels) => {
614
+ const lx = pos === "r" ? wPt - colW + gap : gap;
615
+ let ly = hPt / 2 + entries.length * (sw + 4) / 2 - sw;
616
+ for (const e of entries) {
617
+ rects.push({
618
+ x: lx,
619
+ y: ly,
620
+ w: sw,
621
+ h: sw,
622
+ fillHex: e.colorHex
623
+ });
624
+ labels.push({
625
+ text: e.name,
626
+ x: lx + sw + 3,
627
+ y: ly + 1,
628
+ sizePt: 9,
629
+ colorHex: LABEL_COLOR,
630
+ align: "left"
631
+ });
632
+ ly -= sw + 4;
633
+ }
634
+ }
635
+ };
636
+ }
637
+ const totalW = entries.reduce((acc, e) => acc + entryW(e), 0);
638
+ return {
639
+ rightWidth: 0,
640
+ bottomHeight: sw + 6,
641
+ emit: (rects, labels) => {
642
+ let lx = (wPt - totalW) / 2 + gap;
643
+ const ly = 2;
644
+ for (const e of entries) {
645
+ rects.push({
646
+ x: lx,
647
+ y: ly,
648
+ w: sw,
649
+ h: sw,
650
+ fillHex: e.colorHex
651
+ });
652
+ labels.push({
653
+ text: e.name,
654
+ x: lx + sw + 3,
655
+ y: ly + 1,
656
+ sizePt: 9,
657
+ colorHex: LABEL_COLOR,
658
+ align: "left"
659
+ });
660
+ lx += entryW(e);
661
+ }
662
+ }
663
+ };
664
+ }
665
+ function buildChartScene(chart, wPt, hPt, measure) {
666
+ if (chart.type === "bar") return buildBarScene(chart, wPt, hPt, measure);
667
+ if (chart.type === "line") return buildLineScene(chart, wPt, hPt, measure);
668
+ if (chart.type === "pie") return buildPieScene(chart, wPt, hPt, measure);
669
+ if (chart.type === "area") return buildAreaScene(chart, wPt, hPt, measure);
670
+ if (chart.type === "scatter") return buildScatterScene(chart, wPt, hPt, measure);
671
+ return null;
672
+ }
673
+ //#endregion
674
+ export { buildChartScene };
@@ -0,0 +1,15 @@
1
+ import { ParsedTtf } from '../font/index.js';
2
+ import { PdfRef } from './objects.js';
3
+ import { PdfDocument } from './writer.js';
4
+ export interface EmbedTtfOptions {
5
+ readonly usedGids?: Iterable<number>;
6
+ readonly cidSet?: boolean;
7
+ }
8
+ export interface EmbeddedFont {
9
+ readonly fontRef: PdfRef;
10
+ readonly parsed: ParsedTtf;
11
+ readonly pdfWidthForGid: (gid: number) => number;
12
+ readonly textWidthPt: (text: string, fontSize: number) => number;
13
+ readonly encodeTextAsCidHex: (text: string) => string;
14
+ }
15
+ export declare function embedTtfFont(doc: PdfDocument, parsed: ParsedTtf, options?: EmbedTtfOptions): EmbeddedFont;