@worm-vue3-print/core 1.3.8 → 1.3.10

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.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
@@ -76,7 +76,10 @@ __export(index_exports, {
76
76
  escapeInlineStyleValue: () => escapeInlineStyleValue,
77
77
  evaluate: () => evaluate,
78
78
  evaluateTemplate: () => evaluateTemplate,
79
+ filterFontOptions: () => filterFontOptions,
80
+ findFontOption: () => findFontOption,
79
81
  floorFontSize: () => floorFontSize,
82
+ fontOptionLabel: () => fontOptionLabel,
80
83
  formatDate: () => formatDate,
81
84
  formatMoney: () => formatMoney,
82
85
  formatTimestamp: () => formatTimestamp,
@@ -99,6 +102,8 @@ __export(index_exports, {
99
102
  mm: () => mm,
100
103
  mmToPx: () => mmToPx,
101
104
  multiplyNumbers: () => multiplyNumbers,
105
+ normalizeFontCatalog: () => normalizeFontCatalog,
106
+ normalizeFontQuery: () => normalizeFontQuery,
102
107
  normalizeMeasurements: () => normalizeMeasurements,
103
108
  normalizePrintData: () => normalizePrintData,
104
109
  normalizeTemplate: () => normalizeTemplate,
@@ -114,6 +119,7 @@ __export(index_exports, {
114
119
  renderTemplate: () => renderTemplate,
115
120
  renderWatermarkLayerHtml: () => renderWatermarkLayerHtml,
116
121
  renderWatermarkTileSvg: () => renderWatermarkTileSvg,
122
+ resolveCanvasFontFamily: () => resolveCanvasFontFamily,
117
123
  resolveCellTextFit: () => resolveCellTextFit,
118
124
  resolveElementTextFit: () => resolveElementTextFit,
119
125
  resolvePaperMm: () => resolvePaperMm,
@@ -1064,6 +1070,123 @@ function evaluateTemplate(text, ctx) {
1064
1070
  }
1065
1071
  }
1066
1072
 
1073
+ // src/render/flow-list.ts
1074
+ var FLOW_MIN_COLUMNS = 1;
1075
+ var FLOW_MAX_COLUMNS = 12;
1076
+ var FLOW_MIN_ROW_HEIGHT_MM = 3;
1077
+ var FLOW_MAX_ROW_HEIGHT_MM = 100;
1078
+ var FLOW_MIN_GAP_X_MM = 0;
1079
+ var FLOW_MAX_GAP_X_MM = 50;
1080
+ var PT_TO_MM = 25.4 / 72;
1081
+ function clampInt(value, min2, max2, fallback) {
1082
+ if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
1083
+ return Math.min(max2, Math.max(min2, Math.round(value)));
1084
+ }
1085
+ function resolveFlowColumns(value) {
1086
+ return clampInt(value, FLOW_MIN_COLUMNS, FLOW_MAX_COLUMNS, 4);
1087
+ }
1088
+ function resolveFlowGapX(value) {
1089
+ if (typeof value !== "number" || !Number.isFinite(value)) return 4;
1090
+ return Math.min(FLOW_MAX_GAP_X_MM, Math.max(FLOW_MIN_GAP_X_MM, value));
1091
+ }
1092
+ function resolveFlowRowHeight(value) {
1093
+ if (typeof value !== "number" || !Number.isFinite(value)) return 8;
1094
+ return Math.min(FLOW_MAX_ROW_HEIGHT_MM, Math.max(FLOW_MIN_ROW_HEIGHT_MM, value));
1095
+ }
1096
+ function resolveFlowMaxSpan(value, columns) {
1097
+ const cols = resolveFlowColumns(columns);
1098
+ const fallback = Math.min(2, cols);
1099
+ if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
1100
+ return Math.min(cols, Math.max(1, Math.round(value)));
1101
+ }
1102
+ function flowColumnWidthMm(width, columns, gapX) {
1103
+ const cols = resolveFlowColumns(columns);
1104
+ const gap = resolveFlowGapX(gapX);
1105
+ const avail = width - gap * (cols - 1);
1106
+ if (avail <= 0) return 0;
1107
+ return avail / cols;
1108
+ }
1109
+ function flowSpanWidthMm(colUnitMm, gapX, span) {
1110
+ const k = Math.max(1, Math.floor(span));
1111
+ return colUnitMm * k + gapX * (k - 1);
1112
+ }
1113
+ function estimateTextWidthMm(text, fontSizePt) {
1114
+ if (!text) return 0;
1115
+ const em = typeof fontSizePt === "number" && Number.isFinite(fontSizePt) && fontSizePt > 0 ? fontSizePt * PT_TO_MM : 12 * PT_TO_MM;
1116
+ let units = 0;
1117
+ for (const ch of text) {
1118
+ if (ch === " ") {
1119
+ units += 0.28;
1120
+ continue;
1121
+ }
1122
+ const c = ch.codePointAt(0) ?? 0;
1123
+ if (c >= 12288 && c <= 12351 || c >= 13312 && c <= 19903 || c >= 19968 && c <= 40959 || c >= 63744 && c <= 64255 || c >= 65280 && c <= 65376 || c >= 65504 && c <= 65510 || c >= 131072) units += 1;
1124
+ else if (/^[0-9A-Z]$/.test(ch)) units += 0.6;
1125
+ else if (/^[a-z]$/.test(ch)) units += 0.5;
1126
+ else if (/^[\u0020-\u007f]$/.test(ch)) units += 0.4;
1127
+ else units += 0.75;
1128
+ }
1129
+ return units * em;
1130
+ }
1131
+ function spanForText(text, cfg) {
1132
+ if (!cfg.autoSpan) return 1;
1133
+ const ceiling = resolveFlowMaxSpan(cfg.maxSpan, cfg.columns);
1134
+ if (ceiling <= 1 || cfg.colUnitMm <= 0) return 1;
1135
+ const need = estimateTextWidthMm(text, cfg.fontSizePt);
1136
+ for (let k = 1; k <= ceiling; k++) {
1137
+ if (need <= flowSpanWidthMm(cfg.colUnitMm, cfg.gapX, k)) return k;
1138
+ }
1139
+ return ceiling;
1140
+ }
1141
+ function layoutFlowList(items, cfg) {
1142
+ const columns = resolveFlowColumns(cfg.columns);
1143
+ const gapX = resolveFlowGapX(cfg.gapX);
1144
+ const colUnitMm = flowColumnWidthMm(cfg.width, columns, gapX);
1145
+ const maxSpan = resolveFlowMaxSpan(cfg.maxSpan, columns);
1146
+ const rows = [];
1147
+ let current = [];
1148
+ let used = 0;
1149
+ for (const raw of items) {
1150
+ const text = String(raw ?? "");
1151
+ const span = spanForText(text, { ...cfg, columns, gapX, maxSpan, colUnitMm });
1152
+ if (current.length > 0 && used + span > columns) {
1153
+ rows.push({ cells: current });
1154
+ current = [];
1155
+ used = 0;
1156
+ }
1157
+ current.push({ text, span });
1158
+ used += span;
1159
+ }
1160
+ if (current.length > 0) rows.push({ cells: current });
1161
+ return rows;
1162
+ }
1163
+ function detectFlowListKey(expr, data) {
1164
+ if (typeof expr !== "string" || !expr.includes("{") || !data) return void 0;
1165
+ const roots = /* @__PURE__ */ new Set();
1166
+ for (const token of expr.matchAll(/\{([^{}]*)\}/g)) {
1167
+ for (const piece of (token[1] ?? "").split(/[^A-Za-z0-9_\u4e00-\u9fa5.]/)) {
1168
+ const root = piece.split(".")[0];
1169
+ if (root && !/^\d/.test(root)) roots.add(root);
1170
+ }
1171
+ }
1172
+ for (const root of roots) {
1173
+ if (Array.isArray(data[root])) return root;
1174
+ }
1175
+ return void 0;
1176
+ }
1177
+ var mmNum = (v) => `${Math.round(v * 1e3) / 1e3}mm`;
1178
+ function flowGridStyle(cfg) {
1179
+ const columns = resolveFlowColumns(cfg.columns);
1180
+ const gapX = resolveFlowGapX(cfg.gapX);
1181
+ const rowHeight = resolveFlowRowHeight(cfg.rowHeight);
1182
+ return [
1183
+ `display:grid`,
1184
+ `grid-template-columns:repeat(${columns},minmax(0,1fr))`,
1185
+ `column-gap:${mmNum(gapX)}`,
1186
+ `grid-auto-rows:minmax(${mmNum(rowHeight)},auto)`
1187
+ ].join(";");
1188
+ }
1189
+
1067
1190
  // src/render/data-binder.ts
1068
1191
  function bindData(template, printData, baseUrl, fontBaseUrl) {
1069
1192
  const data = { ...resolveSystemVariables(), ...printData ?? {} };
@@ -1091,7 +1214,8 @@ function bindData(template, printData, baseUrl, fontBaseUrl) {
1091
1214
  }
1092
1215
  function bindElement(el, data, baseUrl) {
1093
1216
  const cloned = { ...el, options: { ...el.options } };
1094
- if (typeof cloned.options.formatter === "string") {
1217
+ const isFlowList = cloned.type === "flowList" || cloned.printElementType?.type === "flowList";
1218
+ if (!isFlowList && typeof cloned.options.formatter === "string") {
1095
1219
  const raw = cloned.options.formatter;
1096
1220
  if (referencesPageNumbers(raw)) {
1097
1221
  cloned.options.rawFormatter = raw;
@@ -1113,8 +1237,23 @@ function bindElement(el, data, baseUrl) {
1113
1237
  if (cloned.type === "table" || cloned.printElementType?.type === "table") {
1114
1238
  bindTableData(cloned, data);
1115
1239
  }
1240
+ if (cloned.type === "flowList" || cloned.printElementType?.type === "flowList") {
1241
+ bindFlowListData(cloned, data);
1242
+ }
1116
1243
  return cloned;
1117
1244
  }
1245
+ function bindFlowListData(el, data) {
1246
+ const template = typeof el.options.formatter === "string" ? el.options.formatter : "";
1247
+ const source = { ...el.options, dataSource: el.options.dataSource ?? detectFlowListKey(template, data) };
1248
+ const { list, key } = resolveListSource(source, data);
1249
+ const itemCtx = (item) => key ? { ...data, ...item, [key]: item } : { ...data, ...item };
1250
+ const items = list.map((item) => {
1251
+ if (!template) return String(item ?? "");
1252
+ return referencesPageNumbers(template) ? template : evaluateTemplate(template, itemCtx(item));
1253
+ });
1254
+ el.options._flowItems = items;
1255
+ el.options._flowRawFormatter = referencesPageNumbers(template) ? template : void 0;
1256
+ }
1118
1257
  function resolveListSource(opts, data) {
1119
1258
  const explicitKey = opts.dataSource ?? opts.fields?.[0]?.dataSource ?? opts.fields?.[0]?.field;
1120
1259
  if (explicitKey && Array.isArray(data[explicitKey])) {
@@ -1190,6 +1329,12 @@ function makeRenderRow(row, resolve, keepRaw = false) {
1190
1329
  barcodeType: cell.barcodeType,
1191
1330
  qrCodeLevel: cell.qrCodeLevel,
1192
1331
  qrQuietZone: cell.qrQuietZone,
1332
+ barQuietZone: cell.barQuietZone,
1333
+ // 条高同样必须进白名单:漏一个,属性台填的 mm 就只在设计器生效、出纸静默按缺省 30 模块
1334
+ barHeight: cell.barHeight,
1335
+ // 条宽与条码文本字号也必须在白名单里:漏一个,属性台填的倍率就只在设计器生效、出纸静默按缺省
1336
+ barWidth: cell.barWidth,
1337
+ barFontSize: cell.barFontSize,
1193
1338
  showBarcodeText: cell.showBarcodeText,
1194
1339
  printerDpi: cell.printerDpi,
1195
1340
  fit: cell.fit,
@@ -1306,6 +1451,57 @@ function toFontFamilyStack(family) {
1306
1451
  const head = name.includes(",") ? name : `"${name.replace(/"/g, "")}"`;
1307
1452
  return [head, ...FALLBACK_FONT_STACK].join(", ");
1308
1453
  }
1454
+ function resolveCanvasFontFamily(family) {
1455
+ return family ? toFontFamilyStack(family) : "inherit";
1456
+ }
1457
+ function normalizeFontCatalog(host) {
1458
+ const out = [];
1459
+ const seen = /* @__PURE__ */ new Set();
1460
+ for (const font of host ?? []) {
1461
+ const family = font?.family?.trim();
1462
+ if (!family) continue;
1463
+ const key = family.toLowerCase();
1464
+ if (seen.has(key)) continue;
1465
+ seen.add(key);
1466
+ const label = font?.label?.trim();
1467
+ out.push(label ? { family, label } : { family });
1468
+ }
1469
+ return out;
1470
+ }
1471
+ function findFontOption(fonts, family) {
1472
+ const key = family?.trim().toLowerCase();
1473
+ if (!key) return void 0;
1474
+ return fonts.find((f) => f.family.trim().toLowerCase() === key);
1475
+ }
1476
+ function fontOptionLabel(option) {
1477
+ return option.label ? `${option.label}\uFF08${option.family}\uFF09` : option.family;
1478
+ }
1479
+ function normalizeFontQuery(value) {
1480
+ return value.toLowerCase().replace(/\s+/g, "");
1481
+ }
1482
+ function matchRank(nameKey, queryKey) {
1483
+ if (nameKey === queryKey) return 0;
1484
+ if (nameKey.startsWith(queryKey)) return 1;
1485
+ if (nameKey.includes(queryKey)) return 2;
1486
+ let cursor = 0;
1487
+ for (const char of nameKey) {
1488
+ if (char === queryKey[cursor]) cursor++;
1489
+ if (cursor === queryKey.length) return 3;
1490
+ }
1491
+ return -1;
1492
+ }
1493
+ function fontMatchRank(font, queryKey) {
1494
+ const byFamily = matchRank(normalizeFontQuery(font.family), queryKey);
1495
+ if (!font.label) return byFamily;
1496
+ const byLabel = matchRank(normalizeFontQuery(font.label), queryKey);
1497
+ if (byFamily < 0) return byLabel;
1498
+ return byLabel < 0 ? byFamily : Math.min(byFamily, byLabel);
1499
+ }
1500
+ function filterFontOptions(fonts, query) {
1501
+ const queryKey = normalizeFontQuery(query.trim());
1502
+ if (!queryKey) return [...fonts];
1503
+ return fonts.map((font, index) => ({ font, index, rank: fontMatchRank(font, queryKey) })).filter((item) => item.rank >= 0).sort((a, b) => a.rank - b.rank || a.index - b.index).map((item) => item.font);
1504
+ }
1309
1505
 
1310
1506
  // src/render/types.ts
1311
1507
  var PAPER_DIMENSIONS = {
@@ -1440,7 +1636,8 @@ function elementBlock() {
1440
1636
  .print-table td {
1441
1637
  border: 1px solid #ccc;
1442
1638
  padding: 2mm 3mm;
1443
- word-break: break-all;
1639
+ word-break: normal;
1640
+ overflow-wrap: break-word;
1444
1641
  overflow: hidden;
1445
1642
  }
1446
1643
  .print-table thead th {
@@ -1672,7 +1869,9 @@ function normalizeFit(value) {
1672
1869
  }
1673
1870
  var ELEMENT_DEFAULT_FIT = {
1674
1871
  text: "clip",
1675
- longText: "autoHeight"
1872
+ longText: "autoHeight",
1873
+ // 流式列表一框一页:超出元素框高的单元按截断处理,不自动撑破纸面(specs 第八节第 8 项)
1874
+ flowList: "clip"
1676
1875
  };
1677
1876
  function resolveElementTextFit(type, opts) {
1678
1877
  return normalizeFit(opts?.textFit) ?? ELEMENT_DEFAULT_FIT[type] ?? "clip";
@@ -1734,6 +1933,7 @@ var SELF_BORDER_TYPES = /* @__PURE__ */ new Set(["rect", "oval", "hline", "vline
1734
1933
  var VALID_STYLES = /* @__PURE__ */ new Set(["solid", "dashed", "dotted", "double"]);
1735
1934
  function parseBorder(width, style, color) {
1736
1935
  if (typeof width !== "number" || !Number.isFinite(width) || width <= 0) return null;
1936
+ if (style === "none") return null;
1737
1937
  return {
1738
1938
  borderWidth: `${width}pt`,
1739
1939
  borderStyle: typeof style === "string" && VALID_STYLES.has(style) ? style : "solid",
@@ -2690,6 +2890,27 @@ function renderElement(el, isMeasure, containerStyle, overrideTop, ctx) {
2690
2890
  return `<div class="print-element" style="${style};border:${opts.borderWidth || 1}pt ${opts.borderStyle || "solid"} ${opts.borderColor || "#333"};border-radius:50%;"${measureAttr}></div>`;
2691
2891
  case "longText":
2692
2892
  return `<div class="print-element" style="${style}${textStyle(opts)}${indentStyle(opts)}${elementFitStyle(fit, opts)}"${measureAttr}${fitAttr}>${esc(opts.formatter ?? opts.testData ?? "")}</div>`;
2893
+ case "flowList": {
2894
+ const columns = resolveFlowColumns(opts.flowColumns);
2895
+ const gapX = resolveFlowGapX(opts.flowGapX);
2896
+ const rowHeight = resolveFlowRowHeight(opts.flowRowHeight);
2897
+ const maxSpan = resolveFlowMaxSpan(opts.flowMaxSpan, columns);
2898
+ const boundItems = Array.isArray(opts._flowItems) ? opts._flowItems : void 0;
2899
+ const items = boundItems && boundItems.length > 0 ? boundItems : String(opts.testData ?? "").split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
2900
+ const cfg = {
2901
+ width,
2902
+ columns,
2903
+ gapX,
2904
+ rowHeight,
2905
+ maxSpan,
2906
+ fontSizePt: opts.fontSize ?? 12,
2907
+ autoSpan: opts.flowAutoSpan === true
2908
+ };
2909
+ const cells = layoutFlowList(items, cfg).flatMap((row) => row.cells).map((c) => `<div class="print-flow-cell"${c.span > 1 ? ` style="grid-column:span ${c.span};"` : ""}>${esc(c.text)}</div>`).join("\n ");
2910
+ return `<div class="print-element" style="${style}${textStyle(opts)}overflow:hidden;${flowGridStyle(cfg)};"${measureAttr}${fitAttr}>
2911
+ ${cells}
2912
+ </div>`;
2913
+ }
2693
2914
  case "html":
2694
2915
  return `<div class="print-element" style="${style}"${measureAttr}>${opts.testData ?? opts.title ?? ""}</div>`;
2695
2916
  default:
@@ -2706,9 +2927,13 @@ function codeImgHtml(value, cellType, opts, io) {
2706
2927
  qrCodeLevel: opts.qrCodeLevel != null ? String(opts.qrCodeLevel) : void 0,
2707
2928
  // 0 是合法档(无白边),必须用 typeof 判定而非 or/?? 之类假值判断
2708
2929
  qrQuietZone: typeof opts.qrQuietZone === "number" ? opts.qrQuietZone : void 0,
2930
+ barQuietZone: typeof opts.barQuietZone === "number" ? opts.barQuietZone : void 0,
2931
+ // 条高(mm):元素台与单元格台都写 barHeight,非法/未填交由布局函数回退缺省档
2932
+ barHeightMm: typeof opts.barHeight === "number" ? opts.barHeight : void 0,
2709
2933
  showText: opts.hideTitle !== void 0 ? !opts.hideTitle : opts.showBarcodeText,
2710
2934
  barWidth: typeof opts.barWidth === "number" ? opts.barWidth : void 0,
2711
- fontSize: typeof opts.fontSize === "number" ? opts.fontSize : void 0,
2935
+ // 元素台的条码文本字号是 fontSize;单元格台的文本字号是 barFontSize(单元格的 fontSize 是正文字号,不该拿来决定条码)
2936
+ fontSize: typeof (opts.barFontSize ?? opts.fontSize) === "number" ? opts.barFontSize ?? opts.fontSize : void 0,
2712
2937
  printerDpi: isBarcode ? io.printerDpi : void 0,
2713
2938
  targetWidthMm: isBarcode ? barcodeAvailableBoxMm(io.targetWidthMm, maxWidth) : void 0,
2714
2939
  targetHeightMm: isBarcode ? barcodeAvailableBoxMm(io.targetHeightMm, maxHeight) : void 0
@@ -2739,8 +2964,9 @@ function matrixCellStyle(cell, opts) {
2739
2964
  const fontSize = cell.fittedFontSize ?? cell.fontSize ?? opts.tableDefaultFontSize;
2740
2965
  const color = cell.color ?? opts.tableDefaultColor;
2741
2966
  const padding = cell.padding ?? opts.tableDefaultPadding ?? 1;
2967
+ const fontFamily = cell.fontFamily ?? opts.tableDefaultFontFamily;
2742
2968
  if (fontSize) parts.push(`font-size:${fontSize}pt`);
2743
- if (cell.fontFamily) parts.push(`font-family:${escapeInlineStyleValue(toFontFamilyStack(cell.fontFamily))}`);
2969
+ if (fontFamily) parts.push(`font-family:${escapeInlineStyleValue(toFontFamilyStack(fontFamily))}`);
2744
2970
  if (cell.fontWeight) parts.push(`font-weight:${cell.fontWeight}`);
2745
2971
  if (color) parts.push(`color:${color}`);
2746
2972
  if (cell.backgroundColor) parts.push(`background-color:${cell.backgroundColor}`);
@@ -2748,7 +2974,7 @@ function matrixCellStyle(cell, opts) {
2748
2974
  if (cell.align === "justify") parts.push("text-align-last:justify");
2749
2975
  parts.push(`vertical-align:${cell.valign ?? "middle"}`);
2750
2976
  parts.push(`padding:${padding}mm`);
2751
- parts.push(cell.wordWrap === false ? "white-space:nowrap;overflow:hidden" : "word-break:break-all");
2977
+ parts.push(cell.wordWrap === false ? "white-space:nowrap;overflow:hidden" : "white-space:pre-wrap;word-break:normal;overflow-wrap:break-word");
2752
2978
  const b = cell.borders ?? {};
2753
2979
  for (const side of ["top", "right", "bottom", "left"]) {
2754
2980
  const border = b[side];
@@ -3132,7 +3358,9 @@ function codeSpecKey(value, cellType, opts = {}) {
3132
3358
  opts.showText ?? null,
3133
3359
  opts.barWidth ?? null,
3134
3360
  opts.fontSize ?? null,
3135
- opts.qrQuietZone ?? null
3361
+ opts.qrQuietZone ?? null,
3362
+ opts.barQuietZone ?? null,
3363
+ opts.barHeightMm ?? null
3136
3364
  ]);
3137
3365
  }
3138
3366
  function createMapCodeRenderer(map) {
@@ -3914,7 +4142,10 @@ var TemplateEngine = class {
3914
4142
  escapeInlineStyleValue,
3915
4143
  evaluate,
3916
4144
  evaluateTemplate,
4145
+ filterFontOptions,
4146
+ findFontOption,
3917
4147
  floorFontSize,
4148
+ fontOptionLabel,
3918
4149
  formatDate,
3919
4150
  formatMoney,
3920
4151
  formatTimestamp,
@@ -3937,6 +4168,8 @@ var TemplateEngine = class {
3937
4168
  mm,
3938
4169
  mmToPx,
3939
4170
  multiplyNumbers,
4171
+ normalizeFontCatalog,
4172
+ normalizeFontQuery,
3940
4173
  normalizeMeasurements,
3941
4174
  normalizePrintData,
3942
4175
  normalizeTemplate,
@@ -3952,6 +4185,7 @@ var TemplateEngine = class {
3952
4185
  renderTemplate,
3953
4186
  renderWatermarkLayerHtml,
3954
4187
  renderWatermarkTileSvg,
4188
+ resolveCanvasFontFamily,
3955
4189
  resolveCellTextFit,
3956
4190
  resolveElementTextFit,
3957
4191
  resolvePaperMm,
package/dist/index.d.cts CHANGED
@@ -1,13 +1,13 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
- import { T as TemplateData, C as CodeRenderer, P as PageLayout, J as MeasuredElement, K as TemplateElement, W as WatermarkOptions, L as PaperMm, N as ViewportPx, O as HeightSource, Q as MarginsMm, S as PdfTargetSpec, R as RawMeasurement, a as CodeSpec, X as CodeRenderOptions, D as DriverFactory, Y as ExecutorBundle, Z as TileLayout, _ as PrintJob, $ as PreparedDocument, a0 as RenderPdfResult, M as MultiPageTemplateData, a1 as PrintFontDeclaration } from './driver-hJxBl2_n.cjs';
8
- export { a2 as ContinuousPaperSize, a3 as EXECUTOR_TARGETS, a4 as ExecutorMethod, a5 as ExecutorTargetKind, a6 as FALLBACK_FONT_STACK, a7 as MAX_BATCH_COPIES, a8 as NormalizedPrintData, a9 as PAPER_DIMENSIONS, aa as PageDriver, ab as PageSection, ac as PaperSize, ad as PrintDataInput, ae as PrintFontFile, af as RenderCell, ag as RenderRequest, ah as RenderRow, ai as SheetPaperSize, aj as TILE_DEFAULTS, H as TextFit, ak as TilingError, al as TilingIssue, am as TilingIssueCode, an as TilingOptions, ao as TilingResolveOptions, ap as TilingTemplateInput, aq as buildFontFaceCss, ar as computeMaxColumns, as as computeTileLayout, at as escapeInlineStyleValue, au as getPaperDimensions, av as isContinuousPaper, aw as isContinuousPaperSize, ax as normalizePrintData, ay as normalizeTilingOptions, az as resolveSheetMm, aA as roundMm, aB as tilePosition, aC as toFontFamilyStack, aD as validateTiling } from './driver-hJxBl2_n.cjs';
9
- import { F as FitFontSize, P as PrintRuntime } from './ports-B-Jb2XwT.cjs';
10
- export { C as CellFitRowKind, i as DEFAULT_READINESS_MS, D as DEFAULT_SHRINK_MIN_FONT_SIZE_PT, j as DEFAULT_TIMEOUT_MS, M as MIN_SHRINK_FONT_SIZE_PT, k as MeasureResult, l as PrintSession, S as SessionBudget, c as cellFitCapMm, a as cellFitKey, f as floorFontSize, p as parseCellFitKey, r as resolveCellTextFit, e as resolveElementTextFit, g as resolveShrinkMinFontSize, h as roundFontSize } from './ports-B-Jb2XwT.cjs';
7
+ import { T as TemplateData, C as CodeRenderer, P as PageLayout, J as MeasuredElement, K as TemplateElement, W as WatermarkOptions, L as PaperMm, N as ViewportPx, O as HeightSource, Q as MarginsMm, S as PdfTargetSpec, R as RawMeasurement, a as CodeSpec, X as CodeRenderOptions, D as DriverFactory, Y as ExecutorBundle, Z as TileLayout, _ as PrintJob, $ as PreparedDocument, a0 as RenderPdfResult, M as MultiPageTemplateData, a1 as PrintFontDeclaration } from './driver-DW3mxuRF.cjs';
8
+ export { a2 as ContinuousPaperSize, a3 as EXECUTOR_TARGETS, a4 as ExecutorMethod, a5 as ExecutorTargetKind, a6 as FALLBACK_FONT_STACK, a7 as FontCatalogOption, a8 as MAX_BATCH_COPIES, a9 as NormalizedPrintData, aa as PAPER_DIMENSIONS, ab as PageDriver, ac as PageSection, ad as PaperSize, ae as PrintDataInput, af as PrintFontFile, ag as RenderCell, ah as RenderRequest, ai as RenderRow, aj as SheetPaperSize, ak as TILE_DEFAULTS, H as TextFit, al as TilingError, am as TilingIssue, an as TilingIssueCode, ao as TilingOptions, ap as TilingResolveOptions, aq as TilingTemplateInput, ar as buildFontFaceCss, as as computeMaxColumns, at as computeTileLayout, au as escapeInlineStyleValue, av as filterFontOptions, aw as findFontOption, ax as fontOptionLabel, ay as getPaperDimensions, az as isContinuousPaper, aA as isContinuousPaperSize, aB as normalizeFontCatalog, aC as normalizeFontQuery, aD as normalizePrintData, aE as normalizeTilingOptions, aF as resolveCanvasFontFamily, aG as resolveSheetMm, aH as roundMm, aI as tilePosition, aJ as toFontFamilyStack, aK as validateTiling } from './driver-DW3mxuRF.cjs';
9
+ import { F as FitFontSize, P as PrintRuntime } from './ports-DJ7_blE7.cjs';
10
+ export { C as CellFitRowKind, i as DEFAULT_READINESS_MS, D as DEFAULT_SHRINK_MIN_FONT_SIZE_PT, j as DEFAULT_TIMEOUT_MS, M as MIN_SHRINK_FONT_SIZE_PT, k as MeasureResult, l as PrintSession, S as SessionBudget, c as cellFitCapMm, a as cellFitKey, f as floorFontSize, p as parseCellFitKey, r as resolveCellTextFit, e as resolveElementTextFit, g as resolveShrinkMinFontSize, h as roundFontSize } from './ports-DJ7_blE7.cjs';
11
11
 
12
12
  type TokenType = 'num' | 'str' | 'bool' | 'ident' | 'punc';
13
13
  interface Token {
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
- import { T as TemplateData, C as CodeRenderer, P as PageLayout, J as MeasuredElement, K as TemplateElement, W as WatermarkOptions, L as PaperMm, N as ViewportPx, O as HeightSource, Q as MarginsMm, S as PdfTargetSpec, R as RawMeasurement, a as CodeSpec, X as CodeRenderOptions, D as DriverFactory, Y as ExecutorBundle, Z as TileLayout, _ as PrintJob, $ as PreparedDocument, a0 as RenderPdfResult, M as MultiPageTemplateData, a1 as PrintFontDeclaration } from './driver-hJxBl2_n.js';
8
- export { a2 as ContinuousPaperSize, a3 as EXECUTOR_TARGETS, a4 as ExecutorMethod, a5 as ExecutorTargetKind, a6 as FALLBACK_FONT_STACK, a7 as MAX_BATCH_COPIES, a8 as NormalizedPrintData, a9 as PAPER_DIMENSIONS, aa as PageDriver, ab as PageSection, ac as PaperSize, ad as PrintDataInput, ae as PrintFontFile, af as RenderCell, ag as RenderRequest, ah as RenderRow, ai as SheetPaperSize, aj as TILE_DEFAULTS, H as TextFit, ak as TilingError, al as TilingIssue, am as TilingIssueCode, an as TilingOptions, ao as TilingResolveOptions, ap as TilingTemplateInput, aq as buildFontFaceCss, ar as computeMaxColumns, as as computeTileLayout, at as escapeInlineStyleValue, au as getPaperDimensions, av as isContinuousPaper, aw as isContinuousPaperSize, ax as normalizePrintData, ay as normalizeTilingOptions, az as resolveSheetMm, aA as roundMm, aB as tilePosition, aC as toFontFamilyStack, aD as validateTiling } from './driver-hJxBl2_n.js';
9
- import { F as FitFontSize, P as PrintRuntime } from './ports-CJ0SUYFt.js';
10
- export { C as CellFitRowKind, i as DEFAULT_READINESS_MS, D as DEFAULT_SHRINK_MIN_FONT_SIZE_PT, j as DEFAULT_TIMEOUT_MS, M as MIN_SHRINK_FONT_SIZE_PT, k as MeasureResult, l as PrintSession, S as SessionBudget, c as cellFitCapMm, a as cellFitKey, f as floorFontSize, p as parseCellFitKey, r as resolveCellTextFit, e as resolveElementTextFit, g as resolveShrinkMinFontSize, h as roundFontSize } from './ports-CJ0SUYFt.js';
7
+ import { T as TemplateData, C as CodeRenderer, P as PageLayout, J as MeasuredElement, K as TemplateElement, W as WatermarkOptions, L as PaperMm, N as ViewportPx, O as HeightSource, Q as MarginsMm, S as PdfTargetSpec, R as RawMeasurement, a as CodeSpec, X as CodeRenderOptions, D as DriverFactory, Y as ExecutorBundle, Z as TileLayout, _ as PrintJob, $ as PreparedDocument, a0 as RenderPdfResult, M as MultiPageTemplateData, a1 as PrintFontDeclaration } from './driver-DW3mxuRF.js';
8
+ export { a2 as ContinuousPaperSize, a3 as EXECUTOR_TARGETS, a4 as ExecutorMethod, a5 as ExecutorTargetKind, a6 as FALLBACK_FONT_STACK, a7 as FontCatalogOption, a8 as MAX_BATCH_COPIES, a9 as NormalizedPrintData, aa as PAPER_DIMENSIONS, ab as PageDriver, ac as PageSection, ad as PaperSize, ae as PrintDataInput, af as PrintFontFile, ag as RenderCell, ah as RenderRequest, ai as RenderRow, aj as SheetPaperSize, ak as TILE_DEFAULTS, H as TextFit, al as TilingError, am as TilingIssue, an as TilingIssueCode, ao as TilingOptions, ap as TilingResolveOptions, aq as TilingTemplateInput, ar as buildFontFaceCss, as as computeMaxColumns, at as computeTileLayout, au as escapeInlineStyleValue, av as filterFontOptions, aw as findFontOption, ax as fontOptionLabel, ay as getPaperDimensions, az as isContinuousPaper, aA as isContinuousPaperSize, aB as normalizeFontCatalog, aC as normalizeFontQuery, aD as normalizePrintData, aE as normalizeTilingOptions, aF as resolveCanvasFontFamily, aG as resolveSheetMm, aH as roundMm, aI as tilePosition, aJ as toFontFamilyStack, aK as validateTiling } from './driver-DW3mxuRF.js';
9
+ import { F as FitFontSize, P as PrintRuntime } from './ports-Brn5xcLD.js';
10
+ export { C as CellFitRowKind, i as DEFAULT_READINESS_MS, D as DEFAULT_SHRINK_MIN_FONT_SIZE_PT, j as DEFAULT_TIMEOUT_MS, M as MIN_SHRINK_FONT_SIZE_PT, k as MeasureResult, l as PrintSession, S as SessionBudget, c as cellFitCapMm, a as cellFitKey, f as floorFontSize, p as parseCellFitKey, r as resolveCellTextFit, e as resolveElementTextFit, g as resolveShrinkMinFontSize, h as roundFontSize } from './ports-Brn5xcLD.js';
11
11
 
12
12
  type TokenType = 'num' | 'str' | 'bool' | 'ident' | 'punc';
13
13
  interface Token {
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
7
  import {
8
8
  TemplateEngine
9
- } from "./chunk-ZKHVOCU5.js";
9
+ } from "./chunk-4ZEP2HSH.js";
10
10
  import {
11
11
  DEFAULT_READINESS_MS,
12
12
  DEFAULT_SHRINK_MIN_FONT_SIZE_PT,
@@ -57,7 +57,10 @@ import {
57
57
  escapeInlineStyleValue,
58
58
  evaluate,
59
59
  evaluateTemplate,
60
+ filterFontOptions,
61
+ findFontOption,
60
62
  floorFontSize,
63
+ fontOptionLabel,
61
64
  formatDate,
62
65
  formatMoney,
63
66
  formatTimestamp,
@@ -80,6 +83,8 @@ import {
80
83
  mm,
81
84
  mmToPx2 as mmToPx,
82
85
  multiplyNumbers,
86
+ normalizeFontCatalog,
87
+ normalizeFontQuery,
83
88
  normalizeMeasurements,
84
89
  normalizePrintData,
85
90
  normalizeTemplate,
@@ -95,6 +100,7 @@ import {
95
100
  renderTemplate,
96
101
  renderWatermarkLayerHtml,
97
102
  renderWatermarkTileSvg,
103
+ resolveCanvasFontFamily,
98
104
  resolveCellTextFit,
99
105
  resolveElementTextFit,
100
106
  resolvePaperMm,
@@ -125,7 +131,7 @@ import {
125
131
  tokenize,
126
132
  validateTiling,
127
133
  withTimeout
128
- } from "./chunk-TQJGFV2V.js";
134
+ } from "./chunk-7FXIWNYK.js";
129
135
  export {
130
136
  DEFAULT_READINESS_MS,
131
137
  DEFAULT_SHRINK_MIN_FONT_SIZE_PT,
@@ -177,7 +183,10 @@ export {
177
183
  escapeInlineStyleValue,
178
184
  evaluate,
179
185
  evaluateTemplate,
186
+ filterFontOptions,
187
+ findFontOption,
180
188
  floorFontSize,
189
+ fontOptionLabel,
181
190
  formatDate,
182
191
  formatMoney,
183
192
  formatTimestamp,
@@ -200,6 +209,8 @@ export {
200
209
  mm,
201
210
  mmToPx,
202
211
  multiplyNumbers,
212
+ normalizeFontCatalog,
213
+ normalizeFontQuery,
203
214
  normalizeMeasurements,
204
215
  normalizePrintData,
205
216
  normalizeTemplate,
@@ -215,6 +226,7 @@ export {
215
226
  renderTemplate,
216
227
  renderWatermarkLayerHtml,
217
228
  renderWatermarkTileSvg,
229
+ resolveCanvasFontFamily,
218
230
  resolveCellTextFit,
219
231
  resolveElementTextFit,
220
232
  resolvePaperMm,
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
- import { Y as ExecutorBundle } from '../driver-hJxBl2_n.cjs';
7
+ import { Y as ExecutorBundle } from '../driver-DW3mxuRF.cjs';
8
8
 
9
9
  /** 读取 core 自带的 DOM 执行器 IIFE 产物;宿主把它注入页面后即可调用 __wormDom */
10
10
  declare function loadExecutorBundle(): ExecutorBundle;
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
- import { Y as ExecutorBundle } from '../driver-hJxBl2_n.js';
7
+ import { Y as ExecutorBundle } from '../driver-DW3mxuRF.js';
8
8
 
9
9
  /** 读取 core 自带的 DOM 执行器 IIFE 产物;宿主把它注入页面后即可调用 __wormDom */
10
10
  declare function loadExecutorBundle(): ExecutorBundle;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
- import { H as TextFit, a as CodeSpec, N as ViewportPx, R as RawMeasurement, S as PdfTargetSpec } from './driver-hJxBl2_n.cjs';
7
+ import { H as TextFit, a as CodeSpec, N as ViewportPx, R as RawMeasurement, S as PdfTargetSpec } from './driver-DW3mxuRF.js';
8
8
 
9
9
  /** 自动缩小的默认下限字号(pt) */
10
10
  declare const DEFAULT_SHRINK_MIN_FONT_SIZE_PT = 6;
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.8
2
+ * @worm-vue3-print/core v1.3.10
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
- import { H as TextFit, a as CodeSpec, N as ViewportPx, R as RawMeasurement, S as PdfTargetSpec } from './driver-hJxBl2_n.js';
7
+ import { H as TextFit, a as CodeSpec, N as ViewportPx, R as RawMeasurement, S as PdfTargetSpec } from './driver-DW3mxuRF.cjs';
8
8
 
9
9
  /** 自动缩小的默认下限字号(pt) */
10
10
  declare const DEFAULT_SHRINK_MIN_FONT_SIZE_PT = 6;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@worm-vue3-print/core",
3
- "version": "1.3.8",
3
+ "version": "1.3.10",
4
4
  "type": "module",
5
5
  "description": "打印模板表达式引擎、同构渲染管线与框架无关的设计器内核(HTML 生成/分页/数据绑定/设计器模型与工具),无 Vue/React 依赖",
6
6
  "main": "dist/index.cjs",