@pdfme/ui 6.1.13-dev.23 → 6.1.13-dev.24

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.
package/dist/index.js CHANGED
@@ -22191,6 +22191,43 @@ var pdfDocEncodingDecode = (bytes) => {
22191
22191
  for (let idx = 0, len = bytes.length; idx < len; idx++) codePoints[idx] = pdfDocEncodingToUnicode[bytes[idx]];
22192
22192
  return String.fromCodePoint(...codePoints);
22193
22193
  };
22194
+ var MARK_CRITICAL_SCRIPTS = [{
22195
+ name: "thai",
22196
+ test: /\p{Script=Thai}/u
22197
+ }, {
22198
+ name: "lao",
22199
+ test: /\p{Script=Lao}/u
22200
+ }];
22201
+ var MARK_CRITICAL_ANY = /[\p{Script=Thai}\p{Script=Lao}]/u;
22202
+ var NEUTRAL = /[\p{Script=Common}\p{Script=Inherited}]/u;
22203
+ var classifyCodePoint = (ch) => {
22204
+ if (NEUTRAL.test(ch)) return null;
22205
+ for (const { name, test } of MARK_CRITICAL_SCRIPTS) if (test.test(ch)) return name;
22206
+ return "default";
22207
+ };
22208
+ /**
22209
+ * Split `text` into shaping runs at Thai/Lao script boundaries.
22210
+ * Concatenating the result always reproduces the input.
22211
+ */
22212
+ var splitTextIntoShapingRuns = (text) => {
22213
+ if (text.length === 0) return [];
22214
+ if (!MARK_CRITICAL_ANY.test(text)) return [text];
22215
+ const runs = [];
22216
+ let current = "";
22217
+ let currentClass = null;
22218
+ for (const ch of text) {
22219
+ const cls = classifyCodePoint(ch);
22220
+ if (!(cls === null || currentClass === null || currentClass === cls) && current.length > 0) {
22221
+ runs.push(current);
22222
+ current = "";
22223
+ currentClass = null;
22224
+ }
22225
+ current += ch;
22226
+ if (cls !== null) currentClass = cls;
22227
+ }
22228
+ if (current.length > 0) runs.push(current);
22229
+ return runs;
22230
+ };
22194
22231
  function _typeof$18(o) {
22195
22232
  "@babel/helpers - typeof";
22196
22233
  return _typeof$18 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -24599,12 +24636,15 @@ var CustomFontEmbedder = class CustomFontEmbedder {
24599
24636
  _defineProperty$13(this, "fontFeatures", void 0);
24600
24637
  _defineProperty$13(this, "baseFontName", void 0);
24601
24638
  _defineProperty$13(this, "glyphCache", void 0);
24639
+ _defineProperty$13(this, "shapedGlyphsById", void 0);
24602
24640
  _defineProperty$13(this, "allGlyphsInFontSortedById", () => {
24603
- const glyphs = Array(this.font.characterSet.length);
24604
- for (let idx = 0, len = glyphs.length; idx < len; idx++) {
24641
+ const glyphs = Array(this.font.characterSet.length + this.shapedGlyphsById.size);
24642
+ for (let idx = 0, len = this.font.characterSet.length; idx < len; idx++) {
24605
24643
  const codePoint = this.font.characterSet[idx];
24606
24644
  glyphs[idx] = this.font.glyphForCodePoint(codePoint);
24607
24645
  }
24646
+ let extraIdx = this.font.characterSet.length;
24647
+ for (const glyph of this.shapedGlyphsById.values()) glyphs[extraIdx++] = glyph;
24608
24648
  return sortedUniq(glyphs.sort(byAscendingId), (g) => g.id);
24609
24649
  });
24610
24650
  this.font = font;
@@ -24614,6 +24654,7 @@ var CustomFontEmbedder = class CustomFontEmbedder {
24614
24654
  this.customName = customName;
24615
24655
  this.fontFeatures = fontFeatures;
24616
24656
  this.baseFontName = "";
24657
+ this.shapedGlyphsById = /* @__PURE__ */ new Map();
24617
24658
  this.glyphCache = Cache.populatedBy(this.allGlyphsInFontSortedById);
24618
24659
  }
24619
24660
  /**
@@ -24621,18 +24662,54 @@ var CustomFontEmbedder = class CustomFontEmbedder {
24621
24662
  * Unicode, but embedded fonts use their own custom encodings)
24622
24663
  */
24623
24664
  encodeText(text) {
24624
- const { glyphs } = this.font.layout(text, this.fontFeatures);
24665
+ const glyphs = this.layoutGlyphs(text);
24625
24666
  const hexCodes = Array(glyphs.length);
24626
24667
  for (let idx = 0, len = glyphs.length; idx < len; idx++) hexCodes[idx] = toHexStringOfMinLength(glyphs[idx].id, 4);
24627
24668
  return PDFHexString.of(hexCodes.join(""));
24628
24669
  }
24629
24670
  widthOfTextAtSize(text, size) {
24630
- const { glyphs } = this.font.layout(text, this.fontFeatures);
24671
+ const glyphs = this.layoutGlyphs(text);
24631
24672
  let totalWidth = 0;
24632
24673
  for (let idx = 0, len = glyphs.length; idx < len; idx++) totalWidth += glyphs[idx].advanceWidth * this.scale;
24633
24674
  const scale = size / 1e3;
24634
24675
  return totalWidth * scale;
24635
24676
  }
24677
+ /**
24678
+ * Layout `text` as one or more fontkit runs. Thai/Lao spans are shaped
24679
+ * separately so GSUB mark variants are selected even when Latin/CJK leads.
24680
+ * A script tag is never passed — each run has one strong script, so fontkit
24681
+ * auto-detection matches the script we would have specified.
24682
+ */
24683
+ layoutGlyphs(text) {
24684
+ const runs = splitTextIntoShapingRuns(text);
24685
+ let glyphs;
24686
+ if (runs.length <= 1) glyphs = this.font.layout(runs[0] ?? "", this.fontFeatures).glyphs;
24687
+ else {
24688
+ glyphs = [];
24689
+ for (const run of runs) {
24690
+ const runGlyphs = this.font.layout(run, this.fontFeatures).glyphs;
24691
+ for (let idx = 0, len = runGlyphs.length; idx < len; idx++) glyphs.push(runGlyphs[idx]);
24692
+ }
24693
+ }
24694
+ this.registerShapedGlyphs(glyphs);
24695
+ return glyphs;
24696
+ }
24697
+ /**
24698
+ * GSUB can emit glyphs that are not in `font.characterSet` (e.g. Sarabun
24699
+ * tone gid 736). Retain those objects so `computeWidths()` and
24700
+ * `embedUnicodeCmap()` include them when the full font is embedded.
24701
+ */
24702
+ registerShapedGlyphs(glyphs) {
24703
+ let added = false;
24704
+ for (let idx = 0, len = glyphs.length; idx < len; idx++) {
24705
+ const glyph = glyphs[idx];
24706
+ if (!this.shapedGlyphsById.has(glyph.id)) {
24707
+ this.shapedGlyphsById.set(glyph.id, glyph);
24708
+ added = true;
24709
+ }
24710
+ }
24711
+ if (added) this.glyphCache.invalidate();
24712
+ }
24636
24713
  heightOfFontAtSize(size, options = {}) {
24637
24714
  const { descender = true } = options;
24638
24715
  const { ascent, descent, bbox } = this.font;
@@ -24767,8 +24844,9 @@ var CustomFontSubsetEmbedder = class CustomFontSubsetEmbedder extends CustomFont
24767
24844
  this.glyphCache = Cache.populatedBy(() => this.glyphs);
24768
24845
  this.glyphIdMap = /* @__PURE__ */ new Map();
24769
24846
  }
24847
+ registerShapedGlyphs(_glyphs) {}
24770
24848
  encodeText(text) {
24771
- const { glyphs } = this.font.layout(text, this.fontFeatures);
24849
+ const glyphs = this.layoutGlyphs(text);
24772
24850
  const hexCodes = Array(glyphs.length);
24773
24851
  for (let idx = 0, len = glyphs.length; idx < len; idx++) {
24774
24852
  const glyph = glyphs[idx];