pdf-codec 1.7.0 → 1.9.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 (52) hide show
  1. package/README.md +21 -14
  2. package/dist/content-write.cjs +26 -5
  3. package/dist/content-write.d.cts +1 -1
  4. package/dist/content-write.d.ts +1 -1
  5. package/dist/content-write.js +27 -6
  6. package/dist/{embedded-font-CLedn-mT.d.cts → embedded-font-BU6Jgcof.d.cts} +7 -1
  7. package/dist/{embedded-font-CbqkKgBl.d.ts → embedded-font-fREdbxnr.d.ts} +7 -1
  8. package/dist/embedded-font-write.d.cts +1 -1
  9. package/dist/embedded-font-write.d.ts +1 -1
  10. package/dist/embedded-font.cjs +22 -5
  11. package/dist/embedded-font.d.cts +2 -2
  12. package/dist/embedded-font.d.ts +2 -2
  13. package/dist/embedded-font.js +22 -5
  14. package/dist/{font-registry-yby02snZ.d.cts → font-registry-B5qL0Vi0.d.cts} +1 -1
  15. package/dist/{font-registry-Cn7P9lAh.d.ts → font-registry-mgdbNP8_.d.ts} +1 -1
  16. package/dist/font-registry.d.cts +1 -1
  17. package/dist/font-registry.d.ts +1 -1
  18. package/dist/formula.d.cts +1 -1
  19. package/dist/formula.d.ts +1 -1
  20. package/dist/gpos-table.cjs +189 -0
  21. package/dist/gpos-table.d.cts +6 -0
  22. package/dist/gpos-table.d.ts +6 -0
  23. package/dist/gpos-table.js +188 -0
  24. package/dist/index.d.cts +6 -6
  25. package/dist/index.d.ts +6 -6
  26. package/dist/math-content-write.cjs +37 -1
  27. package/dist/math-content-write.d.cts +1 -1
  28. package/dist/math-content-write.d.ts +1 -1
  29. package/dist/math-content-write.js +38 -2
  30. package/dist/math-font-write.cjs +6 -1
  31. package/dist/math-font-write.d.cts +1 -1
  32. package/dist/math-font-write.d.ts +1 -1
  33. package/dist/math-font-write.js +6 -1
  34. package/dist/math-font.cjs +48 -0
  35. package/dist/math-font.d.cts +1 -1
  36. package/dist/math-font.d.ts +1 -1
  37. package/dist/math-font.js +48 -0
  38. package/dist/math-table.cjs +7 -21
  39. package/dist/math-table.js +7 -21
  40. package/dist/{math-types-YSQUTviw.d.ts → math-types-BZkWO5Ow.d.cts} +28 -2
  41. package/dist/{math-types-YSQUTviw.d.cts → math-types-Bq7tyV4g.d.ts} +28 -2
  42. package/dist/math-types.d.cts +3 -2
  43. package/dist/math-types.d.ts +3 -2
  44. package/dist/measure.d.cts +1 -1
  45. package/dist/measure.d.ts +1 -1
  46. package/dist/ot-layout-common.cjs +95 -0
  47. package/dist/ot-layout-common.d.cts +10 -0
  48. package/dist/ot-layout-common.d.ts +10 -0
  49. package/dist/ot-layout-common.js +93 -0
  50. package/dist/write.d.cts +2 -2
  51. package/dist/write.d.ts +2 -2
  52. package/package.json +1 -1
@@ -14,6 +14,6 @@ interface MathFontObjects {
14
14
  readonly fontFile: PdfObject;
15
15
  readonly toUnicode: PdfObject;
16
16
  }
17
- declare function buildMathFontObjects(font: MathFont, usedGlyphs: ReadonlyMap<number, number>, refs: MathFontObjectRefs, compress: boolean): MathFontObjects;
17
+ declare function buildMathFontObjects(font: MathFont, usedGlyphs: ReadonlyMap<number, number | undefined>, refs: MathFontObjectRefs, compress: boolean): MathFontObjects;
18
18
  //#endregion
19
19
  export { MathFontObjectRefs, MathFontObjects, buildMathFontObjects };
@@ -14,6 +14,6 @@ interface MathFontObjects {
14
14
  readonly fontFile: PdfObject;
15
15
  readonly toUnicode: PdfObject;
16
16
  }
17
- declare function buildMathFontObjects(font: MathFont, usedGlyphs: ReadonlyMap<number, number>, refs: MathFontObjectRefs, compress: boolean): MathFontObjects;
17
+ declare function buildMathFontObjects(font: MathFont, usedGlyphs: ReadonlyMap<number, number | undefined>, refs: MathFontObjectRefs, compress: boolean): MathFontObjects;
18
18
  //#endregion
19
19
  export { MathFontObjectRefs, MathFontObjects, buildMathFontObjects };
@@ -37,6 +37,11 @@ function buildFontFileStream(font, compress) {
37
37
  } : { Subtype: pdfName("CIDFontType0C") });
38
38
  return pdfStream(dict, compress ? deflate(font.cffBytes) : font.cffBytes);
39
39
  }
40
+ function toUnicodeEntries(usedGlyphs) {
41
+ const entries = /* @__PURE__ */ new Map();
42
+ for (const [glyphId, codePoint] of usedGlyphs) if (codePoint !== void 0) entries.set(glyphId, codePoint);
43
+ return entries;
44
+ }
40
45
  function buildMathFontObjects(font, usedGlyphs, refs, compress) {
41
46
  const cidFont = pdfDict({
42
47
  Type: pdfName("Font"),
@@ -63,7 +68,7 @@ function buildMathFontObjects(font, usedGlyphs, refs, compress) {
63
68
  cidFont,
64
69
  descriptor: buildFontDescriptor(font, refs.fontFileRef),
65
70
  fontFile: buildFontFileStream(font, compress),
66
- toUnicode: buildToUnicodeCMap(usedGlyphs)
71
+ toUnicode: buildToUnicodeCMap(toUnicodeEntries(usedGlyphs))
67
72
  };
68
73
  }
69
74
  //#endregion
@@ -11,6 +11,51 @@ const require_math_table = require("./math-table.cjs");
11
11
  function toPt(designUnits, unitsPerEm, sizePt) {
12
12
  return designUnits / unitsPerEm * sizePt;
13
13
  }
14
+ function measureConstruction(placements, axis, inkBounds, hmtx) {
15
+ let inkAscent = Number.NEGATIVE_INFINITY;
16
+ let inkDescent = Number.NEGATIVE_INFINITY;
17
+ let advanceWidth = 0;
18
+ for (const placement of placements) {
19
+ advanceWidth = Math.max(advanceWidth, hmtx.advanceWidth(placement.glyphId));
20
+ const ink = inkBounds?.bounds(placement.glyphId);
21
+ if (ink === void 0) continue;
22
+ const alongY = axis === "vertical" ? placement.offset : 0;
23
+ inkAscent = Math.max(inkAscent, alongY + ink.yMax);
24
+ inkDescent = Math.max(inkDescent, -(alongY + ink.yMin));
25
+ }
26
+ return inkAscent === Number.NEGATIVE_INFINITY ? void 0 : {
27
+ inkAscent,
28
+ inkDescent,
29
+ advanceWidth
30
+ };
31
+ }
32
+ function stretchAtSize(cmap, hmtx, math, inkBounds, unitsPerEm, codePoint, axis, targetSizePt, sizePt) {
33
+ const glyphId = cmap(codePoint);
34
+ if (glyphId === void 0) return;
35
+ const construction = (axis === "vertical" ? math.variants.vertical : math.variants.horizontal).get(glyphId);
36
+ if (construction === void 0) return;
37
+ const designUnitsPerPt = unitsPerEm / sizePt;
38
+ const assembled = require_math_stretch.assembleStretchyGlyph(construction, {
39
+ axis,
40
+ targetSize: targetSizePt * designUnitsPerPt,
41
+ minConnectorOverlap: math.variants.minConnectorOverlap
42
+ });
43
+ if (assembled === void 0) return;
44
+ const measured = measureConstruction(assembled.placements, axis, inkBounds, hmtx);
45
+ if (measured === void 0) return;
46
+ const pt = (designUnits) => toPt(designUnits, unitsPerEm, sizePt);
47
+ return {
48
+ kind: assembled.kind,
49
+ sizePt: pt(assembled.size),
50
+ advanceWidthPt: pt(measured.advanceWidth),
51
+ inkAscentPt: pt(measured.inkAscent),
52
+ inkDescentPt: pt(measured.inkDescent),
53
+ placements: assembled.placements.map((placement) => ({
54
+ glyphId: placement.glyphId,
55
+ offsetPt: pt(placement.offset)
56
+ }))
57
+ };
58
+ }
14
59
  function metricsAtSize(cmap, hmtx, math, inkBounds, unitsPerEm, ascentDesignUnits, descentDesignUnits, sizePt) {
15
60
  const c = math.constants;
16
61
  const pt = (designUnits) => toPt(designUnits, unitsPerEm, sizePt);
@@ -62,6 +107,9 @@ function metricsAtSize(cmap, hmtx, math, inkBounds, unitsPerEm, ascentDesignUnit
62
107
  inkAscentPt: ink === void 0 ? void 0 : toPt(ink.yMax, unitsPerEm, glyphSizePt),
63
108
  inkDescentPt: ink === void 0 ? void 0 : toPt(-ink.yMin, unitsPerEm, glyphSizePt)
64
109
  };
110
+ },
111
+ stretch(codePoint, axis, targetSizePt, glyphSizePt) {
112
+ return stretchAtSize(cmap, hmtx, math, inkBounds, unitsPerEm, codePoint, axis, targetSizePt, glyphSizePt);
65
113
  }
66
114
  };
67
115
  }
@@ -1,7 +1,7 @@
1
1
  import { t as GlyphInkBounds } from "./glyph-bounds-BV_Z40KS.cjs";
2
- import { r as MathFontMetrics } from "./math-types-YSQUTviw.cjs";
3
2
  import { r as MathGlyphConstruction } from "./math-table-gFNB8DmQ.cjs";
4
3
  import { n as MathStretchConstruction, t as MathStretchAxis } from "./math-stretch-DXWjs8gL.cjs";
4
+ import { i as MathFontMetrics } from "./math-types-BZkWO5Ow.cjs";
5
5
  //#region src/math-font.d.ts
6
6
  interface MathFontDescriptorMetrics {
7
7
  readonly unitsPerEm: number;
@@ -1,7 +1,7 @@
1
1
  import { t as GlyphInkBounds } from "./glyph-bounds-BV_Z40KS.js";
2
- import { r as MathFontMetrics } from "./math-types-YSQUTviw.js";
3
2
  import { r as MathGlyphConstruction } from "./math-table-DhPrNoPa.js";
4
3
  import { n as MathStretchConstruction, t as MathStretchAxis } from "./math-stretch-Bwk_bxh1.js";
4
+ import { i as MathFontMetrics } from "./math-types-Bq7tyV4g.js";
5
5
  //#region src/math-font.d.ts
6
6
  interface MathFontDescriptorMetrics {
7
7
  readonly unitsPerEm: number;
package/dist/math-font.js CHANGED
@@ -10,6 +10,51 @@ import { parseMathTable } from "./math-table.js";
10
10
  function toPt(designUnits, unitsPerEm, sizePt) {
11
11
  return designUnits / unitsPerEm * sizePt;
12
12
  }
13
+ function measureConstruction(placements, axis, inkBounds, hmtx) {
14
+ let inkAscent = Number.NEGATIVE_INFINITY;
15
+ let inkDescent = Number.NEGATIVE_INFINITY;
16
+ let advanceWidth = 0;
17
+ for (const placement of placements) {
18
+ advanceWidth = Math.max(advanceWidth, hmtx.advanceWidth(placement.glyphId));
19
+ const ink = inkBounds?.bounds(placement.glyphId);
20
+ if (ink === void 0) continue;
21
+ const alongY = axis === "vertical" ? placement.offset : 0;
22
+ inkAscent = Math.max(inkAscent, alongY + ink.yMax);
23
+ inkDescent = Math.max(inkDescent, -(alongY + ink.yMin));
24
+ }
25
+ return inkAscent === Number.NEGATIVE_INFINITY ? void 0 : {
26
+ inkAscent,
27
+ inkDescent,
28
+ advanceWidth
29
+ };
30
+ }
31
+ function stretchAtSize(cmap, hmtx, math, inkBounds, unitsPerEm, codePoint, axis, targetSizePt, sizePt) {
32
+ const glyphId = cmap(codePoint);
33
+ if (glyphId === void 0) return;
34
+ const construction = (axis === "vertical" ? math.variants.vertical : math.variants.horizontal).get(glyphId);
35
+ if (construction === void 0) return;
36
+ const designUnitsPerPt = unitsPerEm / sizePt;
37
+ const assembled = assembleStretchyGlyph(construction, {
38
+ axis,
39
+ targetSize: targetSizePt * designUnitsPerPt,
40
+ minConnectorOverlap: math.variants.minConnectorOverlap
41
+ });
42
+ if (assembled === void 0) return;
43
+ const measured = measureConstruction(assembled.placements, axis, inkBounds, hmtx);
44
+ if (measured === void 0) return;
45
+ const pt = (designUnits) => toPt(designUnits, unitsPerEm, sizePt);
46
+ return {
47
+ kind: assembled.kind,
48
+ sizePt: pt(assembled.size),
49
+ advanceWidthPt: pt(measured.advanceWidth),
50
+ inkAscentPt: pt(measured.inkAscent),
51
+ inkDescentPt: pt(measured.inkDescent),
52
+ placements: assembled.placements.map((placement) => ({
53
+ glyphId: placement.glyphId,
54
+ offsetPt: pt(placement.offset)
55
+ }))
56
+ };
57
+ }
13
58
  function metricsAtSize(cmap, hmtx, math, inkBounds, unitsPerEm, ascentDesignUnits, descentDesignUnits, sizePt) {
14
59
  const c = math.constants;
15
60
  const pt = (designUnits) => toPt(designUnits, unitsPerEm, sizePt);
@@ -61,6 +106,9 @@ function metricsAtSize(cmap, hmtx, math, inkBounds, unitsPerEm, ascentDesignUnit
61
106
  inkAscentPt: ink === void 0 ? void 0 : toPt(ink.yMax, unitsPerEm, glyphSizePt),
62
107
  inkDescentPt: ink === void 0 ? void 0 : toPt(-ink.yMin, unitsPerEm, glyphSizePt)
63
108
  };
109
+ },
110
+ stretch(codePoint, axis, targetSizePt, glyphSizePt) {
111
+ return stretchAtSize(cmap, hmtx, math, inkBounds, unitsPerEm, codePoint, axis, targetSizePt, glyphSizePt);
64
112
  }
65
113
  };
66
114
  }
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_sfnt = require("./sfnt.cjs");
3
+ const require_ot_layout_common = require("./ot-layout-common.cjs");
3
4
  //#region src/math-table.ts
4
5
  const MATH_VALUE_RECORD_INDEX = {
5
6
  axisHeight: 1,
@@ -72,28 +73,11 @@ function parseMathConstants(bytes, mathTableOffset) {
72
73
  radicalDegreeBottomRaisePercent: require_sfnt.i16(bytes, constantsOffset + RADICAL_DEGREE_BOTTOM_RAISE_PERCENT_OFFSET)
73
74
  };
74
75
  }
75
- function parseCoverageIndex(bytes, coverageOffset) {
76
- const format = require_sfnt.u16(bytes, coverageOffset);
77
- const index = /* @__PURE__ */ new Map();
78
- if (format === 1) {
79
- const glyphCount = require_sfnt.u16(bytes, coverageOffset + 2);
80
- for (let i = 0; i < glyphCount; i++) index.set(require_sfnt.u16(bytes, coverageOffset + 4 + i * 2), i);
81
- } else if (format === 2) {
82
- const rangeCount = require_sfnt.u16(bytes, coverageOffset + 2);
83
- for (let i = 0; i < rangeCount; i++) {
84
- const recordOffset = coverageOffset + 4 + i * 6;
85
- const startGlyphId = require_sfnt.u16(bytes, recordOffset);
86
- const endGlyphId = require_sfnt.u16(bytes, recordOffset + 2);
87
- const startCoverageIndex = require_sfnt.u16(bytes, recordOffset + 4);
88
- for (let glyphId = startGlyphId; glyphId <= endGlyphId; glyphId++) index.set(glyphId, startCoverageIndex + (glyphId - startGlyphId));
89
- }
90
- }
91
- return index;
92
- }
93
76
  function parseGlyphValueTable(bytes, tableOffset) {
94
- const coverage = parseCoverageIndex(bytes, tableOffset + require_sfnt.u16(bytes, tableOffset));
77
+ const coverage = require_ot_layout_common.parseCoverage(bytes, tableOffset + require_sfnt.u16(bytes, tableOffset));
95
78
  const values = /* @__PURE__ */ new Map();
96
- for (const [glyphId, coverageIndex] of coverage) values.set(glyphId, require_sfnt.i16(bytes, tableOffset + 4 + coverageIndex * 4));
79
+ if (coverage === void 0) return values;
80
+ for (const [glyphId, coverageIndex] of coverage.entries()) values.set(glyphId, require_sfnt.i16(bytes, tableOffset + 4 + coverageIndex * 4));
97
81
  return values;
98
82
  }
99
83
  function parseMathGlyphInfo(bytes, mathTableOffset) {
@@ -146,7 +130,9 @@ function parseGlyphConstruction(bytes, constructionOffset) {
146
130
  function parseConstructionsForAxis(bytes, variantsOffset, coverageOffset, count, constructionArrayOffset) {
147
131
  const constructions = /* @__PURE__ */ new Map();
148
132
  if (coverageOffset === 0) return constructions;
149
- for (const [glyphId, coverageIndex] of parseCoverageIndex(bytes, variantsOffset + coverageOffset)) {
133
+ const coverage = require_ot_layout_common.parseCoverage(bytes, variantsOffset + coverageOffset);
134
+ if (coverage === void 0) return constructions;
135
+ for (const [glyphId, coverageIndex] of coverage.entries()) {
150
136
  if (coverageIndex >= count) continue;
151
137
  constructions.set(glyphId, parseGlyphConstruction(bytes, variantsOffset + require_sfnt.u16(bytes, constructionArrayOffset + coverageIndex * 2)));
152
138
  }
@@ -1,4 +1,5 @@
1
1
  import { i16, sfntTableBytes, u16 } from "./sfnt.js";
2
+ import { parseCoverage } from "./ot-layout-common.js";
2
3
  //#region src/math-table.ts
3
4
  const MATH_VALUE_RECORD_INDEX = {
4
5
  axisHeight: 1,
@@ -71,28 +72,11 @@ function parseMathConstants(bytes, mathTableOffset) {
71
72
  radicalDegreeBottomRaisePercent: i16(bytes, constantsOffset + RADICAL_DEGREE_BOTTOM_RAISE_PERCENT_OFFSET)
72
73
  };
73
74
  }
74
- function parseCoverageIndex(bytes, coverageOffset) {
75
- const format = u16(bytes, coverageOffset);
76
- const index = /* @__PURE__ */ new Map();
77
- if (format === 1) {
78
- const glyphCount = u16(bytes, coverageOffset + 2);
79
- for (let i = 0; i < glyphCount; i++) index.set(u16(bytes, coverageOffset + 4 + i * 2), i);
80
- } else if (format === 2) {
81
- const rangeCount = u16(bytes, coverageOffset + 2);
82
- for (let i = 0; i < rangeCount; i++) {
83
- const recordOffset = coverageOffset + 4 + i * 6;
84
- const startGlyphId = u16(bytes, recordOffset);
85
- const endGlyphId = u16(bytes, recordOffset + 2);
86
- const startCoverageIndex = u16(bytes, recordOffset + 4);
87
- for (let glyphId = startGlyphId; glyphId <= endGlyphId; glyphId++) index.set(glyphId, startCoverageIndex + (glyphId - startGlyphId));
88
- }
89
- }
90
- return index;
91
- }
92
75
  function parseGlyphValueTable(bytes, tableOffset) {
93
- const coverage = parseCoverageIndex(bytes, tableOffset + u16(bytes, tableOffset));
76
+ const coverage = parseCoverage(bytes, tableOffset + u16(bytes, tableOffset));
94
77
  const values = /* @__PURE__ */ new Map();
95
- for (const [glyphId, coverageIndex] of coverage) values.set(glyphId, i16(bytes, tableOffset + 4 + coverageIndex * 4));
78
+ if (coverage === void 0) return values;
79
+ for (const [glyphId, coverageIndex] of coverage.entries()) values.set(glyphId, i16(bytes, tableOffset + 4 + coverageIndex * 4));
96
80
  return values;
97
81
  }
98
82
  function parseMathGlyphInfo(bytes, mathTableOffset) {
@@ -145,7 +129,9 @@ function parseGlyphConstruction(bytes, constructionOffset) {
145
129
  function parseConstructionsForAxis(bytes, variantsOffset, coverageOffset, count, constructionArrayOffset) {
146
130
  const constructions = /* @__PURE__ */ new Map();
147
131
  if (coverageOffset === 0) return constructions;
148
- for (const [glyphId, coverageIndex] of parseCoverageIndex(bytes, variantsOffset + coverageOffset)) {
132
+ const coverage = parseCoverage(bytes, variantsOffset + coverageOffset);
133
+ if (coverage === void 0) return constructions;
134
+ for (const [glyphId, coverageIndex] of coverage.entries()) {
149
135
  if (coverageIndex >= count) continue;
150
136
  constructions.set(glyphId, parseGlyphConstruction(bytes, variantsOffset + u16(bytes, constructionArrayOffset + coverageIndex * 2)));
151
137
  }
@@ -1,3 +1,4 @@
1
+ import { t as MathStretchAxis } from "./math-stretch-DXWjs8gL.cjs";
1
2
  //#region src/math-types.d.ts
2
3
  interface MathColor {
3
4
  readonly r: number;
@@ -29,7 +30,19 @@ interface MathStroke {
29
30
  readonly widthPt: number;
30
31
  readonly color: MathColor;
31
32
  }
32
- type MathLayoutItem = MathGlyphRun | MathRule | MathStroke;
33
+ interface MathGlyphPlacement {
34
+ readonly glyphId: number;
35
+ readonly xPt: number;
36
+ readonly yPt: number;
37
+ }
38
+ interface MathAssembledGlyphs {
39
+ readonly kind: 'assembled-glyphs';
40
+ readonly placements: readonly MathGlyphPlacement[];
41
+ readonly text: string;
42
+ readonly sizePt: number;
43
+ readonly color: MathColor;
44
+ }
45
+ type MathLayoutItem = MathGlyphRun | MathRule | MathStroke | MathAssembledGlyphs;
33
46
  interface MathBox {
34
47
  readonly widthPt: number;
35
48
  readonly heightPt: number;
@@ -44,6 +57,18 @@ interface MathGlyphMetrics {
44
57
  readonly inkAscentPt?: number;
45
58
  readonly inkDescentPt?: number;
46
59
  }
60
+ interface MathStretchGlyph {
61
+ readonly glyphId: number;
62
+ readonly offsetPt: number;
63
+ }
64
+ interface MathStretchResult {
65
+ readonly kind: 'base' | 'variant' | 'assembly';
66
+ readonly sizePt: number;
67
+ readonly advanceWidthPt: number;
68
+ readonly inkAscentPt: number;
69
+ readonly inkDescentPt: number;
70
+ readonly placements: readonly MathStretchGlyph[];
71
+ }
47
72
  interface MathFontMetrics {
48
73
  readonly ascentPerEm: number;
49
74
  readonly descentPerEm: number;
@@ -79,6 +104,7 @@ interface MathFontMetrics {
79
104
  readonly scriptScriptPercentScaleDown: number;
80
105
  readonly defaultRuleThicknessPt: number;
81
106
  glyph(codePoint: number, sizePt: number): MathGlyphMetrics | undefined;
107
+ stretch(codePoint: number, axis: MathStretchAxis, targetSizePt: number, sizePt: number): MathStretchResult | undefined;
82
108
  }
83
109
  //#endregion
84
- export { MathGlyphRun as a, MathStroke as c, MathGlyphMetrics as i, MathColor as n, MathLayoutItem as o, MathFontMetrics as r, MathRule as s, MathBox as t };
110
+ export { MathGlyphMetrics as a, MathLayoutItem as c, MathStretchResult as d, MathStroke as f, MathFontMetrics as i, MathRule as l, MathBox as n, MathGlyphPlacement as o, MathColor as r, MathGlyphRun as s, MathAssembledGlyphs as t, MathStretchGlyph as u };
@@ -1,3 +1,4 @@
1
+ import { t as MathStretchAxis } from "./math-stretch-Bwk_bxh1.js";
1
2
  //#region src/math-types.d.ts
2
3
  interface MathColor {
3
4
  readonly r: number;
@@ -29,7 +30,19 @@ interface MathStroke {
29
30
  readonly widthPt: number;
30
31
  readonly color: MathColor;
31
32
  }
32
- type MathLayoutItem = MathGlyphRun | MathRule | MathStroke;
33
+ interface MathGlyphPlacement {
34
+ readonly glyphId: number;
35
+ readonly xPt: number;
36
+ readonly yPt: number;
37
+ }
38
+ interface MathAssembledGlyphs {
39
+ readonly kind: 'assembled-glyphs';
40
+ readonly placements: readonly MathGlyphPlacement[];
41
+ readonly text: string;
42
+ readonly sizePt: number;
43
+ readonly color: MathColor;
44
+ }
45
+ type MathLayoutItem = MathGlyphRun | MathRule | MathStroke | MathAssembledGlyphs;
33
46
  interface MathBox {
34
47
  readonly widthPt: number;
35
48
  readonly heightPt: number;
@@ -44,6 +57,18 @@ interface MathGlyphMetrics {
44
57
  readonly inkAscentPt?: number;
45
58
  readonly inkDescentPt?: number;
46
59
  }
60
+ interface MathStretchGlyph {
61
+ readonly glyphId: number;
62
+ readonly offsetPt: number;
63
+ }
64
+ interface MathStretchResult {
65
+ readonly kind: 'base' | 'variant' | 'assembly';
66
+ readonly sizePt: number;
67
+ readonly advanceWidthPt: number;
68
+ readonly inkAscentPt: number;
69
+ readonly inkDescentPt: number;
70
+ readonly placements: readonly MathStretchGlyph[];
71
+ }
47
72
  interface MathFontMetrics {
48
73
  readonly ascentPerEm: number;
49
74
  readonly descentPerEm: number;
@@ -79,6 +104,7 @@ interface MathFontMetrics {
79
104
  readonly scriptScriptPercentScaleDown: number;
80
105
  readonly defaultRuleThicknessPt: number;
81
106
  glyph(codePoint: number, sizePt: number): MathGlyphMetrics | undefined;
107
+ stretch(codePoint: number, axis: MathStretchAxis, targetSizePt: number, sizePt: number): MathStretchResult | undefined;
82
108
  }
83
109
  //#endregion
84
- export { MathGlyphRun as a, MathStroke as c, MathGlyphMetrics as i, MathColor as n, MathLayoutItem as o, MathFontMetrics as r, MathRule as s, MathBox as t };
110
+ export { MathGlyphMetrics as a, MathLayoutItem as c, MathStretchResult as d, MathStroke as f, MathFontMetrics as i, MathRule as l, MathBox as n, MathGlyphPlacement as o, MathColor as r, MathGlyphRun as s, MathAssembledGlyphs as t, MathStretchGlyph as u };
@@ -1,2 +1,3 @@
1
- import { a as MathGlyphRun, c as MathStroke, i as MathGlyphMetrics, n as MathColor, o as MathLayoutItem, r as MathFontMetrics, s as MathRule, t as MathBox } from "./math-types-YSQUTviw.cjs";
2
- export { MathBox, MathColor, MathFontMetrics, MathGlyphMetrics, MathGlyphRun, MathLayoutItem, MathRule, MathStroke };
1
+ import { t as MathStretchAxis } from "./math-stretch-DXWjs8gL.cjs";
2
+ import { a as MathGlyphMetrics, c as MathLayoutItem, d as MathStretchResult, f as MathStroke, i as MathFontMetrics, l as MathRule, n as MathBox, o as MathGlyphPlacement, r as MathColor, s as MathGlyphRun, t as MathAssembledGlyphs, u as MathStretchGlyph } from "./math-types-BZkWO5Ow.cjs";
3
+ export { MathAssembledGlyphs, MathBox, MathColor, MathFontMetrics, MathGlyphMetrics, MathGlyphPlacement, MathGlyphRun, MathLayoutItem, MathRule, type MathStretchAxis, MathStretchGlyph, MathStretchResult, MathStroke };
@@ -1,2 +1,3 @@
1
- import { a as MathGlyphRun, c as MathStroke, i as MathGlyphMetrics, n as MathColor, o as MathLayoutItem, r as MathFontMetrics, s as MathRule, t as MathBox } from "./math-types-YSQUTviw.js";
2
- export { MathBox, MathColor, MathFontMetrics, MathGlyphMetrics, MathGlyphRun, MathLayoutItem, MathRule, MathStroke };
1
+ import { t as MathStretchAxis } from "./math-stretch-Bwk_bxh1.js";
2
+ import { a as MathGlyphMetrics, c as MathLayoutItem, d as MathStretchResult, f as MathStroke, i as MathFontMetrics, l as MathRule, n as MathBox, o as MathGlyphPlacement, r as MathColor, s as MathGlyphRun, t as MathAssembledGlyphs, u as MathStretchGlyph } from "./math-types-Bq7tyV4g.js";
3
+ export { MathAssembledGlyphs, MathBox, MathColor, MathFontMetrics, MathGlyphMetrics, MathGlyphPlacement, MathGlyphRun, MathLayoutItem, MathRule, type MathStretchAxis, MathStretchGlyph, MathStretchResult, MathStroke };
@@ -1,4 +1,4 @@
1
- import { t as FontRegistry } from "./font-registry-yby02snZ.cjs";
1
+ import { t as FontRegistry } from "./font-registry-B5qL0Vi0.cjs";
2
2
  import { LayoutFont } from "document-schema.js";
3
3
  //#region src/measure.d.ts
4
4
  interface UnderlineMetrics {
package/dist/measure.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as FontRegistry } from "./font-registry-Cn7P9lAh.js";
1
+ import { t as FontRegistry } from "./font-registry-mgdbNP8_.js";
2
2
  import { LayoutFont } from "document-schema.js";
3
3
  //#region src/measure.d.ts
4
4
  interface UnderlineMetrics {
@@ -0,0 +1,95 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_sfnt = require("./sfnt.cjs");
3
+ //#region src/ot-layout-common.ts
4
+ function findRange(ranges, glyphId) {
5
+ let low = 0;
6
+ let high = ranges.length - 1;
7
+ while (low <= high) {
8
+ const mid = low + high >> 1;
9
+ const range = ranges[mid];
10
+ if (glyphId < range.startGlyphId) high = mid - 1;
11
+ else if (glyphId > range.endGlyphId) low = mid + 1;
12
+ else return range;
13
+ }
14
+ }
15
+ function pushGlyph(ranges, glyphId, value, valueStep) {
16
+ const previous = ranges[ranges.length - 1];
17
+ if (previous !== void 0 && glyphId === previous.endGlyphId + 1 && value === previous.value + (previous.endGlyphId - previous.startGlyphId + 1) * valueStep) {
18
+ ranges[ranges.length - 1] = {
19
+ startGlyphId: previous.startGlyphId,
20
+ endGlyphId: glyphId,
21
+ value: previous.value
22
+ };
23
+ return;
24
+ }
25
+ ranges.push({
26
+ startGlyphId: glyphId,
27
+ endGlyphId: glyphId,
28
+ value
29
+ });
30
+ }
31
+ const RANGE_RECORD_SIZE = 6;
32
+ function parseRangeRecords(bytes, recordsOffset, recordCount) {
33
+ if (!require_sfnt.hasBytes(bytes, recordsOffset, recordCount * RANGE_RECORD_SIZE)) return;
34
+ const ranges = [];
35
+ for (let i = 0; i < recordCount; i++) {
36
+ const recordOffset = recordsOffset + i * RANGE_RECORD_SIZE;
37
+ const startGlyphId = require_sfnt.u16(bytes, recordOffset);
38
+ const endGlyphId = require_sfnt.u16(bytes, recordOffset + 2);
39
+ if (endGlyphId < startGlyphId) continue;
40
+ ranges.push({
41
+ startGlyphId,
42
+ endGlyphId,
43
+ value: require_sfnt.u16(bytes, recordOffset + 4)
44
+ });
45
+ }
46
+ ranges.sort((a, b) => a.startGlyphId - b.startGlyphId);
47
+ return ranges;
48
+ }
49
+ const COVERAGE_HEADER_SIZE = 4;
50
+ function parseCoverage(bytes, coverageOffset) {
51
+ if (!require_sfnt.hasBytes(bytes, coverageOffset, COVERAGE_HEADER_SIZE)) return;
52
+ const format = require_sfnt.u16(bytes, coverageOffset);
53
+ const count = require_sfnt.u16(bytes, coverageOffset + 2);
54
+ let ranges;
55
+ if (format === 1) {
56
+ const glyphArrayOffset = coverageOffset + COVERAGE_HEADER_SIZE;
57
+ if (!require_sfnt.hasBytes(bytes, glyphArrayOffset, count * 2)) return;
58
+ ranges = [];
59
+ for (let i = 0; i < count; i++) pushGlyph(ranges, require_sfnt.u16(bytes, glyphArrayOffset + i * 2), i, 1);
60
+ ranges.sort((a, b) => a.startGlyphId - b.startGlyphId);
61
+ } else if (format === 2) ranges = parseRangeRecords(bytes, coverageOffset + COVERAGE_HEADER_SIZE, count);
62
+ if (ranges === void 0) return;
63
+ const resolved = ranges;
64
+ return {
65
+ coverageIndex(glyphId) {
66
+ const range = findRange(resolved, glyphId);
67
+ return range === void 0 ? void 0 : range.value + (glyphId - range.startGlyphId);
68
+ },
69
+ *entries() {
70
+ for (const range of resolved) for (let glyphId = range.startGlyphId; glyphId <= range.endGlyphId; glyphId++) yield [glyphId, range.value + (glyphId - range.startGlyphId)];
71
+ }
72
+ };
73
+ }
74
+ const CLASS_DEF_FORMAT_1_HEADER_SIZE = 6;
75
+ const CLASS_DEF_FORMAT_2_HEADER_SIZE = 4;
76
+ function parseClassDef(bytes, classDefOffset) {
77
+ if (!require_sfnt.hasBytes(bytes, classDefOffset, CLASS_DEF_FORMAT_2_HEADER_SIZE)) return;
78
+ const format = require_sfnt.u16(bytes, classDefOffset);
79
+ let ranges;
80
+ if (format === 1) {
81
+ if (!require_sfnt.hasBytes(bytes, classDefOffset, CLASS_DEF_FORMAT_1_HEADER_SIZE)) return;
82
+ const startGlyphId = require_sfnt.u16(bytes, classDefOffset + 2);
83
+ const glyphCount = require_sfnt.u16(bytes, classDefOffset + 4);
84
+ const classArrayOffset = classDefOffset + CLASS_DEF_FORMAT_1_HEADER_SIZE;
85
+ if (!require_sfnt.hasBytes(bytes, classArrayOffset, glyphCount * 2)) return;
86
+ ranges = [];
87
+ for (let i = 0; i < glyphCount; i++) pushGlyph(ranges, startGlyphId + i, require_sfnt.u16(bytes, classArrayOffset + i * 2), 0);
88
+ } else if (format === 2) ranges = parseRangeRecords(bytes, classDefOffset + CLASS_DEF_FORMAT_2_HEADER_SIZE, require_sfnt.u16(bytes, classDefOffset + 2));
89
+ if (ranges === void 0) return;
90
+ const resolved = ranges;
91
+ return (glyphId) => findRange(resolved, glyphId)?.value ?? 0;
92
+ }
93
+ //#endregion
94
+ exports.parseClassDef = parseClassDef;
95
+ exports.parseCoverage = parseCoverage;
@@ -0,0 +1,10 @@
1
+ //#region src/ot-layout-common.d.ts
2
+ interface CoverageTable {
3
+ coverageIndex(glyphId: number): number | undefined;
4
+ entries(): IterableIterator<readonly [number, number]>;
5
+ }
6
+ declare function parseCoverage(bytes: Uint8Array<ArrayBuffer>, coverageOffset: number): CoverageTable | undefined;
7
+ type ClassDefTable = (glyphId: number) => number;
8
+ declare function parseClassDef(bytes: Uint8Array<ArrayBuffer>, classDefOffset: number): ClassDefTable | undefined;
9
+ //#endregion
10
+ export { ClassDefTable, CoverageTable, parseClassDef, parseCoverage };
@@ -0,0 +1,10 @@
1
+ //#region src/ot-layout-common.d.ts
2
+ interface CoverageTable {
3
+ coverageIndex(glyphId: number): number | undefined;
4
+ entries(): IterableIterator<readonly [number, number]>;
5
+ }
6
+ declare function parseCoverage(bytes: Uint8Array<ArrayBuffer>, coverageOffset: number): CoverageTable | undefined;
7
+ type ClassDefTable = (glyphId: number) => number;
8
+ declare function parseClassDef(bytes: Uint8Array<ArrayBuffer>, classDefOffset: number): ClassDefTable | undefined;
9
+ //#endregion
10
+ export { ClassDefTable, CoverageTable, parseClassDef, parseCoverage };
@@ -0,0 +1,93 @@
1
+ import { hasBytes, u16 } from "./sfnt.js";
2
+ //#region src/ot-layout-common.ts
3
+ function findRange(ranges, glyphId) {
4
+ let low = 0;
5
+ let high = ranges.length - 1;
6
+ while (low <= high) {
7
+ const mid = low + high >> 1;
8
+ const range = ranges[mid];
9
+ if (glyphId < range.startGlyphId) high = mid - 1;
10
+ else if (glyphId > range.endGlyphId) low = mid + 1;
11
+ else return range;
12
+ }
13
+ }
14
+ function pushGlyph(ranges, glyphId, value, valueStep) {
15
+ const previous = ranges[ranges.length - 1];
16
+ if (previous !== void 0 && glyphId === previous.endGlyphId + 1 && value === previous.value + (previous.endGlyphId - previous.startGlyphId + 1) * valueStep) {
17
+ ranges[ranges.length - 1] = {
18
+ startGlyphId: previous.startGlyphId,
19
+ endGlyphId: glyphId,
20
+ value: previous.value
21
+ };
22
+ return;
23
+ }
24
+ ranges.push({
25
+ startGlyphId: glyphId,
26
+ endGlyphId: glyphId,
27
+ value
28
+ });
29
+ }
30
+ const RANGE_RECORD_SIZE = 6;
31
+ function parseRangeRecords(bytes, recordsOffset, recordCount) {
32
+ if (!hasBytes(bytes, recordsOffset, recordCount * RANGE_RECORD_SIZE)) return;
33
+ const ranges = [];
34
+ for (let i = 0; i < recordCount; i++) {
35
+ const recordOffset = recordsOffset + i * RANGE_RECORD_SIZE;
36
+ const startGlyphId = u16(bytes, recordOffset);
37
+ const endGlyphId = u16(bytes, recordOffset + 2);
38
+ if (endGlyphId < startGlyphId) continue;
39
+ ranges.push({
40
+ startGlyphId,
41
+ endGlyphId,
42
+ value: u16(bytes, recordOffset + 4)
43
+ });
44
+ }
45
+ ranges.sort((a, b) => a.startGlyphId - b.startGlyphId);
46
+ return ranges;
47
+ }
48
+ const COVERAGE_HEADER_SIZE = 4;
49
+ function parseCoverage(bytes, coverageOffset) {
50
+ if (!hasBytes(bytes, coverageOffset, COVERAGE_HEADER_SIZE)) return;
51
+ const format = u16(bytes, coverageOffset);
52
+ const count = u16(bytes, coverageOffset + 2);
53
+ let ranges;
54
+ if (format === 1) {
55
+ const glyphArrayOffset = coverageOffset + COVERAGE_HEADER_SIZE;
56
+ if (!hasBytes(bytes, glyphArrayOffset, count * 2)) return;
57
+ ranges = [];
58
+ for (let i = 0; i < count; i++) pushGlyph(ranges, u16(bytes, glyphArrayOffset + i * 2), i, 1);
59
+ ranges.sort((a, b) => a.startGlyphId - b.startGlyphId);
60
+ } else if (format === 2) ranges = parseRangeRecords(bytes, coverageOffset + COVERAGE_HEADER_SIZE, count);
61
+ if (ranges === void 0) return;
62
+ const resolved = ranges;
63
+ return {
64
+ coverageIndex(glyphId) {
65
+ const range = findRange(resolved, glyphId);
66
+ return range === void 0 ? void 0 : range.value + (glyphId - range.startGlyphId);
67
+ },
68
+ *entries() {
69
+ for (const range of resolved) for (let glyphId = range.startGlyphId; glyphId <= range.endGlyphId; glyphId++) yield [glyphId, range.value + (glyphId - range.startGlyphId)];
70
+ }
71
+ };
72
+ }
73
+ const CLASS_DEF_FORMAT_1_HEADER_SIZE = 6;
74
+ const CLASS_DEF_FORMAT_2_HEADER_SIZE = 4;
75
+ function parseClassDef(bytes, classDefOffset) {
76
+ if (!hasBytes(bytes, classDefOffset, CLASS_DEF_FORMAT_2_HEADER_SIZE)) return;
77
+ const format = u16(bytes, classDefOffset);
78
+ let ranges;
79
+ if (format === 1) {
80
+ if (!hasBytes(bytes, classDefOffset, CLASS_DEF_FORMAT_1_HEADER_SIZE)) return;
81
+ const startGlyphId = u16(bytes, classDefOffset + 2);
82
+ const glyphCount = u16(bytes, classDefOffset + 4);
83
+ const classArrayOffset = classDefOffset + CLASS_DEF_FORMAT_1_HEADER_SIZE;
84
+ if (!hasBytes(bytes, classArrayOffset, glyphCount * 2)) return;
85
+ ranges = [];
86
+ for (let i = 0; i < glyphCount; i++) pushGlyph(ranges, startGlyphId + i, u16(bytes, classArrayOffset + i * 2), 0);
87
+ } else if (format === 2) ranges = parseRangeRecords(bytes, classDefOffset + CLASS_DEF_FORMAT_2_HEADER_SIZE, u16(bytes, classDefOffset + 2));
88
+ if (ranges === void 0) return;
89
+ const resolved = ranges;
90
+ return (glyphId) => findRange(resolved, glyphId)?.value ?? 0;
91
+ }
92
+ //#endregion
93
+ export { parseClassDef, parseCoverage };
package/dist/write.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { r as EmbeddedFaceSubstitution } from "./embedded-font-CLedn-mT.cjs";
2
- import { t as FontRegistry } from "./font-registry-yby02snZ.cjs";
1
+ import { r as EmbeddedFaceSubstitution } from "./embedded-font-BU6Jgcof.cjs";
2
+ import { t as FontRegistry } from "./font-registry-B5qL0Vi0.cjs";
3
3
  import { WinAnsiSubstitution } from "./winansi.cjs";
4
4
  import { PositionedFormula } from "./formula.cjs";
5
5
  import { LayoutDocument } from "document-schema.js";
package/dist/write.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { r as EmbeddedFaceSubstitution } from "./embedded-font-CbqkKgBl.js";
2
- import { t as FontRegistry } from "./font-registry-Cn7P9lAh.js";
1
+ import { r as EmbeddedFaceSubstitution } from "./embedded-font-fREdbxnr.js";
2
+ import { t as FontRegistry } from "./font-registry-mgdbNP8_.js";
3
3
  import { WinAnsiSubstitution } from "./winansi.js";
4
4
  import { PositionedFormula } from "./formula.js";
5
5
  import { LayoutDocument } from "document-schema.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-codec",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "description": "Hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs and generates new ones, built on document-schema.js's LayoutDocument pivot and Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {