@office-kit/pptx-preview 0.9.0 → 0.9.1

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
@@ -1,2 +1,2 @@
1
- import { a as MONO, c as TIMES, d as substituteFamily, l as defaultMeasurer, n as renderSlideSvg, o as SANS, r as ARIAL, s as SERIF, t as auditTextLayout } from "./src-DPHsJGe1.js";
1
+ import { a as MONO, c as TIMES, d as substituteFamily, l as defaultMeasurer, n as renderSlideSvg, o as SANS, r as ARIAL, s as SERIF, t as auditTextLayout } from "./src-C_bsFwWV.js";
2
2
  export { ARIAL, MONO, SANS, SERIF, TIMES, auditTextLayout, defaultMeasurer, renderSlideSvg as renderSlideToSvg, substituteFamily };
package/dist/node.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as MONO, c as TIMES, d as substituteFamily, i as AVG_GLYPH_W_RATIO, l as defaultMeasurer, n as renderSlideSvg, o as SANS, r as ARIAL, s as SERIF, t as auditTextLayout, u as isCjk } from "./src-DPHsJGe1.js";
1
+ import { a as MONO, c as TIMES, d as substituteFamily, i as AVG_GLYPH_W_RATIO, l as defaultMeasurer, n as renderSlideSvg, o as SANS, r as ARIAL, s as SERIF, t as auditTextLayout, u as isCjk } from "./src-C_bsFwWV.js";
2
2
  import { getSlideSize } from "@office-kit/pptx";
3
3
  import { Resvg } from "@resvg/resvg-js";
4
4
  import * as fontkit from "fontkit";
@@ -32,6 +32,29 @@ const FALLBACK_DESCENT = .22;
32
32
  const FALLBACK_LINEGAP = .08;
33
33
  const BASELINE_LEADING_DROP = .036;
34
34
  const GRID_NUDGE_X = -.75;
35
+ const EAST_ASIAN_CHAR = /[ᄀ-ᅟ⺀-〾ぁ-㏿㐀-䶿一-鿿ꀀ-꓏가-힣豈-﫿︰-﹏＀-⦆¢-₩]/;
36
+ const CLOSING_PUNCT = /^[、。,.・)」』】〉》”’!?:;ー〜…,.!?:;)\]}]+$/;
37
+ const OPENING_PUNCT = /^[(「『【〈《“‘([{]+$/;
38
+ const splitEastAsianBreakables = (word) => {
39
+ if (!EAST_ASIAN_CHAR.test(word)) return [word];
40
+ const parts = [];
41
+ let latin = "";
42
+ for (const ch of word) if (EAST_ASIAN_CHAR.test(ch)) {
43
+ if (latin !== "") {
44
+ parts.push(latin);
45
+ latin = "";
46
+ }
47
+ parts.push(ch);
48
+ } else latin += ch;
49
+ if (latin !== "") parts.push(latin);
50
+ const glued = [];
51
+ for (const part of parts) {
52
+ const prev = glued.at(-1);
53
+ if (prev !== void 0 && (CLOSING_PUNCT.test(part) || OPENING_PUNCT.test(prev))) glued[glued.length - 1] = prev + part;
54
+ else glued.push(part);
55
+ }
56
+ return glued;
57
+ };
35
58
  const specOf = (piece) => ({
36
59
  family: piece.family,
37
60
  sizePx: piece.sizePx,
@@ -113,23 +136,25 @@ const layoutCore = (input, measure) => {
113
136
  });
114
137
  continue;
115
138
  }
116
- for (const seg of piece.text.match(/\s+|\S+/g) ?? []) {
117
- const isSpace = /^\s+$/.test(seg);
118
- const w = mWidth(seg, specOf(piece));
119
- if (input.wrap && !isSpace && w > avail - bulletLead && [...seg].length > 1) for (const ch of seg) tokens.push({
120
- text: ch,
121
- piece,
122
- isSpace: false,
123
- isBreak: false,
124
- width: mWidth(ch, specOf(piece))
125
- });
126
- else tokens.push({
127
- text: seg,
128
- piece,
129
- isSpace,
130
- isBreak: false,
131
- width: w
132
- });
139
+ for (const word of piece.text.match(/\s+|\S+/g) ?? []) {
140
+ const isSpace = /^\s+$/.test(word);
141
+ for (const seg of isSpace ? [word] : splitEastAsianBreakables(word)) {
142
+ const w = mWidth(seg, specOf(piece));
143
+ if (input.wrap && !isSpace && w > avail - bulletLead && [...seg].length > 1) for (const ch of seg) tokens.push({
144
+ text: ch,
145
+ piece,
146
+ isSpace: false,
147
+ isBreak: false,
148
+ width: mWidth(ch, specOf(piece))
149
+ });
150
+ else tokens.push({
151
+ text: seg,
152
+ piece,
153
+ isSpace,
154
+ isBreak: false,
155
+ width: w
156
+ });
157
+ }
133
158
  }
134
159
  }
135
160
  const wrapped = wrapTokens(tokens, input.wrap, wrapRight - firstLeft - bulletLead, avail);
@@ -2772,6 +2797,12 @@ const renderChartTitle = (f, title, style) => {
2772
2797
  const fontStyleAttr = style?.italic ? " font-style=\"italic\"" : "";
2773
2798
  return `<text x="${px(f.x + f.w / 2)}" y="${px(f.titleY)}" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="${chartFontPx(sz)}" fill="${fill}" font-weight="${weight}"${fontStyleAttr}>${escapeXml(title)}</text>`;
2774
2799
  };
2800
+ const FULLWIDTH_CHAR_PATTERN = /[\u1100-\u115F\u2E80-\u303E\u3041-\u33FF\u3400-\u4DBF\u4E00-\u9FFF\uA000-\uA4CF\uAC00-\uD7A3\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFF60\uFFE0-\uFFE6]/u;
2801
+ const approxLegendTextPx = (text, fontPx) => {
2802
+ let units = 0;
2803
+ for (const ch of text) units += FULLWIDTH_CHAR_PATTERN.test(ch) ? 1 : .55;
2804
+ return units * fontPx;
2805
+ };
2775
2806
  const renderChartLegend = (f, names, colors, position = "b", textStyle, markerSymbols) => {
2776
2807
  if (names.length === 0) return "";
2777
2808
  const sz = textStyle?.sizePt ?? 11;
@@ -2789,33 +2820,27 @@ const renderChartLegend = (f, names, colors, position = "b", textStyle, markerSy
2789
2820
  return `<rect x="${px(swatchX)}" y="${px(swatchY)}" width="9" height="9" fill="${color}"/>`;
2790
2821
  };
2791
2822
  const out = [];
2792
- if (position === "b") {
2793
- const itemPx = Math.min(140, f.w / names.length);
2794
- const totalW = itemPx * names.length;
2795
- const startX = f.x + (f.w - totalW) / 2;
2796
- for (let i = 0; i < names.length; i++) {
2797
- const swatchX = startX + i * itemPx + 4;
2798
- const swatchY = f.legendY - 4;
2799
- const labelX = swatchX + 14;
2800
- out.push(swatch(i, swatchX, swatchY), `<text x="${px(labelX)}" y="${px(f.legendY)}" dominant-baseline="middle" ${textAttrs}>${escapeXml(names[i] ?? `Series ${i + 1}`)}</text>`);
2801
- }
2802
- return out.join("");
2803
- }
2804
- if (position === "t") {
2805
- const itemPx = Math.min(140, f.w / names.length);
2806
- const totalW = itemPx * names.length;
2807
- const startX = f.x + (f.w - totalW) / 2;
2808
- const yTop = f.y + 4;
2823
+ if (position === "b" || position === "t") {
2824
+ const swatchGapPx = 14;
2825
+ const itemGapPx = 12;
2826
+ const labelWidths = names.map((name, i) => approxLegendTextPx(name ?? `Series ${i + 1}`, sz * PX_PER_PT));
2827
+ const naturalTotal = labelWidths.reduce((sum, w) => sum + swatchGapPx + w, 0) + itemGapPx * (names.length - 1);
2828
+ const scale = Math.min(1, f.w / Math.max(1, naturalTotal));
2829
+ const effAttrs = scale < 1 ? `font-family="sans-serif" font-size="${chartFontPx(sz * scale)}" fill="${fill}"${weight}${italic}` : textAttrs;
2830
+ const rowY = position === "b" ? f.legendY : f.y + 12;
2831
+ let cursor = f.x + Math.max(0, (f.w - naturalTotal * scale) / 2);
2809
2832
  for (let i = 0; i < names.length; i++) {
2810
- const cx = startX + i * itemPx;
2811
- out.push(swatch(i, cx + 4, yTop), `<text x="${px(cx + 18)}" y="${px(yTop + 8)}" dominant-baseline="middle" ${textAttrs}>${escapeXml(names[i] ?? `Series ${i + 1}`)}</text>`);
2833
+ out.push(swatch(i, cursor, rowY - 4), `<text x="${px(cursor + swatchGapPx * scale)}" y="${px(rowY)}" dominant-baseline="middle" ${effAttrs}>${escapeXml(names[i] ?? `Series ${i + 1}`)}</text>`);
2834
+ cursor += (swatchGapPx + (labelWidths[i] ?? 0) + itemGapPx) * scale;
2812
2835
  }
2813
2836
  return out.join("");
2814
2837
  }
2815
2838
  const lineH = 14;
2816
2839
  const totalH = names.length * lineH;
2817
2840
  const yStart = position === "tr" ? f.y + 12 : Math.max(f.y + 12, f.y + (f.h - totalH) / 2);
2818
- const xCol = position === "l" ? f.x + 6 : position === "tr" ? f.x + f.w - 100 : f.x + f.w - 100;
2841
+ const maxLabelPx = Math.max(0, ...names.map((name, i) => approxLegendTextPx(name ?? `Series ${i + 1}`, sz * PX_PER_PT)));
2842
+ const rightColW = Math.min(f.w * .45, 14 + maxLabelPx + 4);
2843
+ const xCol = position === "l" ? f.x + 6 : f.x + f.w - rightColW;
2819
2844
  for (let i = 0; i < names.length; i++) {
2820
2845
  const yp = yStart + i * lineH;
2821
2846
  out.push(swatch(i, xCol, yp - 4), `<text x="${px(xCol + 14)}" y="${px(yp + 4)}" dominant-baseline="middle" ${textAttrs}>${escapeXml(names[i] ?? `Series ${i + 1}`)}</text>`);
@@ -4660,4 +4685,4 @@ const auditTextLayout = (pres, options = {}) => {
4660
4685
  //#endregion
4661
4686
  export { MONO as a, TIMES as c, substituteFamily as d, AVG_GLYPH_W_RATIO as i, defaultMeasurer as l, renderSlideSvg as n, SANS as o, ARIAL as r, SERIF as s, auditTextLayout as t, isCjk as u };
4662
4687
 
4663
- //# sourceMappingURL=src-DPHsJGe1.js.map
4688
+ //# sourceMappingURL=src-C_bsFwWV.js.map