pptx-glimpse 3.0.0 → 3.1.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.
package/dist/index.cjs CHANGED
@@ -929,84 +929,6 @@ var init_cjk_font_fallback = __esm({
929
929
  }
930
930
  });
931
931
 
932
- // ../renderer/src/unsafe-type-assertion.ts
933
- function unsafeExternalInteropAssertion(value) {
934
- return value;
935
- }
936
- function unsafeBrandAssertion(value) {
937
- return value;
938
- }
939
- var init_unsafe_type_assertion = __esm({
940
- "../renderer/src/unsafe-type-assertion.ts"() {
941
- "use strict";
942
- }
943
- });
944
-
945
- // ../renderer/src/warning-logger.ts
946
- function initWarningLogger(level) {
947
- currentLevel = level;
948
- entries = [];
949
- featureCounts.clear();
950
- }
951
- function warn(feature, message, context) {
952
- if (currentLevel === "off") return;
953
- entries.push({ feature, message, ...context !== void 0 && { context } });
954
- const existing = featureCounts.get(feature);
955
- if (existing) {
956
- existing.count++;
957
- } else {
958
- featureCounts.set(feature, { message, count: 1 });
959
- }
960
- if (currentLevel === "debug") {
961
- const ctx = context ? ` (${context})` : "";
962
- console.warn(`${PREFIX} SKIP: ${feature} - ${message}${ctx}`);
963
- }
964
- }
965
- function debug(feature, message, context) {
966
- if (currentLevel !== "debug") return;
967
- entries.push({ feature, message, ...context !== void 0 && { context } });
968
- const existing = featureCounts.get(feature);
969
- if (existing) {
970
- existing.count++;
971
- } else {
972
- featureCounts.set(feature, { message, count: 1 });
973
- }
974
- const ctx = context ? ` (${context})` : "";
975
- console.warn(`${PREFIX} DEBUG: ${feature} - ${message}${ctx}`);
976
- }
977
- function getWarningSummary() {
978
- const features = [];
979
- for (const [feature, { message, count }] of featureCounts) {
980
- features.push({ feature, message, count });
981
- }
982
- return { totalCount: entries.length, features };
983
- }
984
- function flushWarnings() {
985
- const summary = getWarningSummary();
986
- if (currentLevel !== "off" && summary.features.length > 0) {
987
- console.warn(`${PREFIX} Summary: ${summary.features.length} unsupported feature(s) detected`);
988
- for (const { feature, count } of summary.features) {
989
- console.warn(` - ${feature}: ${count} occurrence(s)`);
990
- }
991
- }
992
- entries = [];
993
- featureCounts.clear();
994
- return summary;
995
- }
996
- function getWarningEntries() {
997
- return entries;
998
- }
999
- var PREFIX, currentLevel, entries, featureCounts;
1000
- var init_warning_logger = __esm({
1001
- "../renderer/src/warning-logger.ts"() {
1002
- "use strict";
1003
- PREFIX = "[pptx-glimpse]";
1004
- currentLevel = "off";
1005
- entries = [];
1006
- featureCounts = /* @__PURE__ */ new Map();
1007
- }
1008
- });
1009
-
1010
932
  // ../renderer/src/font/font-mapping.ts
1011
933
  function createFontMapping(userMapping) {
1012
934
  if (!userMapping) return { ...DEFAULT_FONT_MAPPING };
@@ -1068,11 +990,8 @@ var init_font_mapping = __esm({
1068
990
  });
1069
991
 
1070
992
  // ../renderer/src/font/font-mapping-context.ts
1071
- function setFontMapping(mapping) {
1072
- currentMapping = mapping;
1073
- }
1074
- function resetFontMapping() {
1075
- currentMapping = { ...DEFAULT_FONT_MAPPING };
993
+ function getFontMapping() {
994
+ return currentMapping;
1076
995
  }
1077
996
  function getCurrentMappedFont(fontFamily) {
1078
997
  return getMappedFont(fontFamily, currentMapping);
@@ -1184,6 +1103,169 @@ var init_text_measure = __esm({
1184
1103
  }
1185
1104
  });
1186
1105
 
1106
+ // ../renderer/src/warning-logger.ts
1107
+ function createWarningLogger(level) {
1108
+ return new InMemoryWarningLogger(level);
1109
+ }
1110
+ function getActiveWarningLogger() {
1111
+ return activeLogger;
1112
+ }
1113
+ function warn(feature, message, context) {
1114
+ activeLogger.warn(feature, message, context);
1115
+ }
1116
+ function getWarningSummary() {
1117
+ return activeLogger.getWarningSummary();
1118
+ }
1119
+ function getWarningEntries() {
1120
+ return activeLogger.getWarningEntries();
1121
+ }
1122
+ var PREFIX, InMemoryWarningLogger, activeLogger;
1123
+ var init_warning_logger = __esm({
1124
+ "../renderer/src/warning-logger.ts"() {
1125
+ "use strict";
1126
+ PREFIX = "[pptx-glimpse]";
1127
+ InMemoryWarningLogger = class {
1128
+ constructor(level) {
1129
+ this.level = level;
1130
+ }
1131
+ level;
1132
+ entries = [];
1133
+ featureCounts = /* @__PURE__ */ new Map();
1134
+ warn(feature, message, context) {
1135
+ if (this.level === "off") return;
1136
+ this.record(feature, message, context);
1137
+ if (this.level === "debug") {
1138
+ const ctx = context ? ` (${context})` : "";
1139
+ console.warn(`${PREFIX} SKIP: ${feature} - ${message}${ctx}`);
1140
+ }
1141
+ }
1142
+ debug(feature, message, context) {
1143
+ if (this.level !== "debug") return;
1144
+ this.record(feature, message, context);
1145
+ const ctx = context ? ` (${context})` : "";
1146
+ console.warn(`${PREFIX} DEBUG: ${feature} - ${message}${ctx}`);
1147
+ }
1148
+ getWarningSummary() {
1149
+ const features = [];
1150
+ for (const [feature, { message, count }] of this.featureCounts) {
1151
+ features.push({ feature, message, count });
1152
+ }
1153
+ return { totalCount: this.entries.length, features };
1154
+ }
1155
+ flushWarnings() {
1156
+ const summary = this.getWarningSummary();
1157
+ if (this.level !== "off" && summary.features.length > 0) {
1158
+ console.warn(`${PREFIX} Summary: ${summary.features.length} unsupported feature(s) detected`);
1159
+ for (const { feature, count } of summary.features) {
1160
+ console.warn(` - ${feature}: ${count} occurrence(s)`);
1161
+ }
1162
+ }
1163
+ this.entries = [];
1164
+ this.featureCounts.clear();
1165
+ return summary;
1166
+ }
1167
+ getWarningEntries() {
1168
+ return this.entries;
1169
+ }
1170
+ getLogLevel() {
1171
+ return this.level;
1172
+ }
1173
+ record(feature, message, context) {
1174
+ this.entries.push({ feature, message, ...context !== void 0 && { context } });
1175
+ const existing = this.featureCounts.get(feature);
1176
+ if (existing) {
1177
+ existing.count++;
1178
+ } else {
1179
+ this.featureCounts.set(feature, { message, count: 1 });
1180
+ }
1181
+ }
1182
+ };
1183
+ activeLogger = createWarningLogger("off");
1184
+ }
1185
+ });
1186
+
1187
+ // ../renderer/src/font/text-path-context.ts
1188
+ function getTextPathFontResolver() {
1189
+ return currentResolver;
1190
+ }
1191
+ var DefaultTextPathFontResolver, currentResolver;
1192
+ var init_text_path_context = __esm({
1193
+ "../renderer/src/font/text-path-context.ts"() {
1194
+ "use strict";
1195
+ init_warning_logger();
1196
+ init_cjk_font_fallback();
1197
+ init_font_mapping();
1198
+ init_font_mapping_context();
1199
+ DefaultTextPathFontResolver = class {
1200
+ fonts;
1201
+ defaultFont;
1202
+ warnedFonts = /* @__PURE__ */ new Set();
1203
+ constructor(fonts, defaultFont) {
1204
+ this.fonts = fonts;
1205
+ this.defaultFont = defaultFont ?? null;
1206
+ }
1207
+ resolveFont(fontFamily, fontFamilyEa, jpanFallback, context) {
1208
+ if (fontFamily) {
1209
+ const font = this.findFont(fontFamily, context);
1210
+ if (font) return font;
1211
+ }
1212
+ if (fontFamilyEa) {
1213
+ const font = this.findFont(fontFamilyEa, context);
1214
+ if (font) return font;
1215
+ }
1216
+ if (jpanFallback) {
1217
+ const font = this.findFont(jpanFallback, context);
1218
+ if (font) return font;
1219
+ }
1220
+ for (const name of [fontFamily, fontFamilyEa, jpanFallback]) {
1221
+ if (name) {
1222
+ const logger = context?.warningLogger;
1223
+ if (logger) {
1224
+ if (context.fontWarningCache?.has(name)) continue;
1225
+ context.fontWarningCache?.add(name);
1226
+ logger.warn("font.notFound", `Font not found: "${name}"`);
1227
+ continue;
1228
+ }
1229
+ if (!this.warnedFonts.has(name)) {
1230
+ this.warnedFonts.add(name);
1231
+ warn("font.notFound", `Font not found: "${name}"`);
1232
+ }
1233
+ }
1234
+ }
1235
+ return this.defaultFont;
1236
+ }
1237
+ findFont(name, context) {
1238
+ const direct = this.fonts.get(name);
1239
+ if (direct) return direct;
1240
+ const mapped = context?.fontMapping !== void 0 ? getMappedFont(name, context.fontMapping) : getCurrentMappedFont(name);
1241
+ if (mapped) {
1242
+ const mappedFont = this.fonts.get(mapped);
1243
+ if (mappedFont) return mappedFont;
1244
+ for (const fallback of getCjkFallbackFonts(mapped)) {
1245
+ const fallbackFont = this.fonts.get(fallback);
1246
+ if (fallbackFont) return fallbackFont;
1247
+ }
1248
+ }
1249
+ return null;
1250
+ }
1251
+ };
1252
+ currentResolver = null;
1253
+ }
1254
+ });
1255
+
1256
+ // ../renderer/src/unsafe-type-assertion.ts
1257
+ function unsafeExternalInteropAssertion(value) {
1258
+ return value;
1259
+ }
1260
+ function unsafeBrandAssertion(value) {
1261
+ return value;
1262
+ }
1263
+ var init_unsafe_type_assertion = __esm({
1264
+ "../renderer/src/unsafe-type-assertion.ts"() {
1265
+ "use strict";
1266
+ }
1267
+ });
1268
+
1187
1269
  // ../renderer/src/font/opentype-text-measurer.ts
1188
1270
  var PX_PER_PT2, BOLD_FACTOR2, OpentypeTextMeasurer;
1189
1271
  var init_opentype_text_measurer = __esm({
@@ -1192,24 +1274,27 @@ var init_opentype_text_measurer = __esm({
1192
1274
  init_text_measure();
1193
1275
  init_warning_logger();
1194
1276
  init_cjk_font_fallback();
1277
+ init_font_mapping();
1195
1278
  init_font_mapping_context();
1196
1279
  PX_PER_PT2 = 96 / 72;
1197
1280
  BOLD_FACTOR2 = 1.05;
1198
1281
  OpentypeTextMeasurer = class {
1199
- fonts;
1200
- defaultFont;
1201
- warnedFonts = /* @__PURE__ */ new Set();
1202
1282
  /**
1203
1283
  * @param fonts - font name -> opentype.js Map of Font objects
1204
1284
  * @param defaultFont - fallback font (optional)
1205
1285
  */
1206
- constructor(fonts, defaultFont) {
1286
+ constructor(fonts, defaultFont, fontMapping) {
1287
+ this.fontMapping = fontMapping;
1207
1288
  this.fonts = fonts;
1208
1289
  this.defaultFont = defaultFont ?? null;
1209
1290
  }
1210
- measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa) {
1211
- const latinFont = this.resolveFont(fontFamily);
1212
- const eaFont = this.resolveFont(fontFamilyEa);
1291
+ fontMapping;
1292
+ fonts;
1293
+ defaultFont;
1294
+ warnedFonts = /* @__PURE__ */ new Set();
1295
+ measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa, context) {
1296
+ const latinFont = this.resolveFont(fontFamily, context);
1297
+ const eaFont = this.resolveFont(fontFamilyEa, context);
1213
1298
  const fallbackFont = latinFont ?? eaFont ?? this.defaultFont;
1214
1299
  if (!fallbackFont) {
1215
1300
  return measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa);
@@ -1217,7 +1302,7 @@ var init_opentype_text_measurer = __esm({
1217
1302
  const fontSizePx = fontSizePt * PX_PER_PT2;
1218
1303
  const latinFontResolved = latinFont ?? fallbackFont;
1219
1304
  const eaFontResolved = eaFont ?? fallbackFont;
1220
- const boldLatinFont = bold ? this.resolveBoldFont(fontFamily) : null;
1305
+ const boldLatinFont = bold ? this.resolveBoldFont(fontFamily, context) : null;
1221
1306
  const latinGlyphCache = /* @__PURE__ */ new Map();
1222
1307
  const eaGlyphCache = eaFontResolved !== latinFontResolved ? /* @__PURE__ */ new Map() : latinGlyphCache;
1223
1308
  const boldGlyphCache = /* @__PURE__ */ new Map();
@@ -1249,26 +1334,26 @@ var init_opentype_text_measurer = __esm({
1249
1334
  }
1250
1335
  return totalWidth;
1251
1336
  }
1252
- getLineHeightRatio(fontFamily, fontFamilyEa) {
1253
- const font = this.resolveFont(fontFamily) ?? this.resolveFont(fontFamilyEa) ?? this.defaultFont;
1337
+ getLineHeightRatio(fontFamily, fontFamilyEa, context) {
1338
+ const font = this.resolveFont(fontFamily, context) ?? this.resolveFont(fontFamilyEa, context) ?? this.defaultFont;
1254
1339
  if (!font) return 1.2;
1255
1340
  return (font.ascender + Math.abs(font.descender)) / font.unitsPerEm;
1256
1341
  }
1257
- getAscenderRatio(fontFamily, fontFamilyEa) {
1258
- const font = this.resolveFont(fontFamily) ?? this.resolveFont(fontFamilyEa) ?? this.defaultFont;
1342
+ getAscenderRatio(fontFamily, fontFamilyEa, context) {
1343
+ const font = this.resolveFont(fontFamily, context) ?? this.resolveFont(fontFamilyEa, context) ?? this.defaultFont;
1259
1344
  if (!font) return 1;
1260
1345
  return font.ascender / font.unitsPerEm;
1261
1346
  }
1262
- resolveBoldFont(name) {
1347
+ resolveBoldFont(name, context) {
1263
1348
  if (!name) return null;
1264
1349
  const bases = [name];
1265
- const mappedBase = getCurrentMappedFont(name);
1350
+ const mappedBase = this.getMappedFont(name, context);
1266
1351
  if (mappedBase && mappedBase !== name) bases.push(mappedBase);
1267
1352
  for (const base of bases) {
1268
1353
  for (const boldName of [`${base} Bold`, `${base}-Bold`]) {
1269
1354
  const direct = this.fonts.get(boldName);
1270
1355
  if (direct) return direct;
1271
- const mapped = getCurrentMappedFont(boldName);
1356
+ const mapped = this.getMappedFont(boldName, context);
1272
1357
  if (mapped) {
1273
1358
  const mappedFont = this.fonts.get(mapped);
1274
1359
  if (mappedFont) return mappedFont;
@@ -1277,11 +1362,11 @@ var init_opentype_text_measurer = __esm({
1277
1362
  }
1278
1363
  return null;
1279
1364
  }
1280
- resolveFont(name) {
1365
+ resolveFont(name, context) {
1281
1366
  if (!name) return null;
1282
1367
  const direct = this.fonts.get(name);
1283
1368
  if (direct) return direct;
1284
- const mapped = getCurrentMappedFont(name);
1369
+ const mapped = this.getMappedFont(name, context);
1285
1370
  if (mapped) {
1286
1371
  const mappedFont = this.fonts.get(mapped);
1287
1372
  if (mappedFont) return mappedFont;
@@ -1290,78 +1375,20 @@ var init_opentype_text_measurer = __esm({
1290
1375
  if (fallbackFont) return fallbackFont;
1291
1376
  }
1292
1377
  }
1293
- if (!this.warnedFonts.has(name)) {
1378
+ if (context?.warningLogger) {
1379
+ if (context.fontWarningCache?.has(name)) return null;
1380
+ context.fontWarningCache?.add(name);
1381
+ context.warningLogger.warn("font.notFound", `Font not found: "${name}"`);
1382
+ } else if (!this.warnedFonts.has(name)) {
1294
1383
  this.warnedFonts.add(name);
1295
1384
  warn("font.notFound", `Font not found: "${name}"`);
1296
1385
  }
1297
1386
  return null;
1298
1387
  }
1299
- };
1300
- }
1301
- });
1302
-
1303
- // ../renderer/src/font/text-path-context.ts
1304
- function setTextPathFontResolver(resolver) {
1305
- currentResolver = resolver;
1306
- }
1307
- function getTextPathFontResolver() {
1308
- return currentResolver;
1309
- }
1310
- function resetTextPathFontResolver() {
1311
- currentResolver = null;
1312
- }
1313
- var DefaultTextPathFontResolver, currentResolver;
1314
- var init_text_path_context = __esm({
1315
- "../renderer/src/font/text-path-context.ts"() {
1316
- "use strict";
1317
- init_warning_logger();
1318
- init_cjk_font_fallback();
1319
- init_font_mapping_context();
1320
- DefaultTextPathFontResolver = class {
1321
- fonts;
1322
- defaultFont;
1323
- warnedFonts = /* @__PURE__ */ new Set();
1324
- constructor(fonts, defaultFont) {
1325
- this.fonts = fonts;
1326
- this.defaultFont = defaultFont ?? null;
1327
- }
1328
- resolveFont(fontFamily, fontFamilyEa, jpanFallback) {
1329
- if (fontFamily) {
1330
- const font = this.findFont(fontFamily);
1331
- if (font) return font;
1332
- }
1333
- if (fontFamilyEa) {
1334
- const font = this.findFont(fontFamilyEa);
1335
- if (font) return font;
1336
- }
1337
- if (jpanFallback) {
1338
- const font = this.findFont(jpanFallback);
1339
- if (font) return font;
1340
- }
1341
- for (const name of [fontFamily, fontFamilyEa, jpanFallback]) {
1342
- if (name && !this.warnedFonts.has(name)) {
1343
- this.warnedFonts.add(name);
1344
- warn("font.notFound", `Font not found: "${name}"`);
1345
- }
1346
- }
1347
- return this.defaultFont;
1348
- }
1349
- findFont(name) {
1350
- const direct = this.fonts.get(name);
1351
- if (direct) return direct;
1352
- const mapped = getCurrentMappedFont(name);
1353
- if (mapped) {
1354
- const mappedFont = this.fonts.get(mapped);
1355
- if (mappedFont) return mappedFont;
1356
- for (const fallback of getCjkFallbackFonts(mapped)) {
1357
- const fallbackFont = this.fonts.get(fallback);
1358
- if (fallbackFont) return fallbackFont;
1359
- }
1360
- }
1361
- return null;
1388
+ getMappedFont(name, context) {
1389
+ return context?.fontMapping !== void 0 ? getMappedFont(name, context.fontMapping) : this.fontMapping !== void 0 ? getMappedFont(name, this.fontMapping) : getCurrentMappedFont(name);
1362
1390
  }
1363
1391
  };
1364
- currentResolver = null;
1365
1392
  }
1366
1393
  });
1367
1394
 
@@ -1561,11 +1588,12 @@ function collectFontNames(font) {
1561
1588
  }
1562
1589
  return names;
1563
1590
  }
1564
- function buildOpentypeSetupFromState(state) {
1591
+ function buildOpentypeSetupFromState(state, fontMapping) {
1565
1592
  if (state.measurerFonts.size === 0 && !state.firstMeasurerFont) return null;
1566
1593
  const measurer = new OpentypeTextMeasurer(
1567
1594
  state.measurerFonts,
1568
- state.firstMeasurerFont ?? void 0
1595
+ state.firstMeasurerFont ?? void 0,
1596
+ fontMapping
1569
1597
  );
1570
1598
  const fontResolver = new DefaultTextPathFontResolver(
1571
1599
  state.resolverFonts,
@@ -1594,7 +1622,7 @@ async function createOpentypeSetupFromBuffers(fontBuffers, fontMapping) {
1594
1622
  } catch {
1595
1623
  }
1596
1624
  }
1597
- return buildOpentypeSetupFromState(state);
1625
+ return buildOpentypeSetupFromState(state, mapping);
1598
1626
  }
1599
1627
  function getSystemFontCacheStore() {
1600
1628
  const globalObject = globalThis;
@@ -1719,7 +1747,8 @@ async function createOpentypeSetupFromSystem(additionalFontDirs, fontMapping, sk
1719
1747
  if (!opentype) return null;
1720
1748
  const fontFilePaths = collectFontFilePaths(additionalFontDirs, skipSystemFonts);
1721
1749
  if (fontFilePaths.length === 0) return null;
1722
- const reverseMap = buildReverseMapping(createFontMapping(fontMapping));
1750
+ const mapping = createFontMapping(fontMapping);
1751
+ const reverseMap = buildReverseMapping(mapping);
1723
1752
  const state = createOpentypeSetupState();
1724
1753
  for (const filePath of fontFilePaths) {
1725
1754
  try {
@@ -1732,7 +1761,7 @@ async function createOpentypeSetupFromSystem(additionalFontDirs, fontMapping, sk
1732
1761
  } catch {
1733
1762
  }
1734
1763
  }
1735
- const setup = buildOpentypeSetupFromState(state);
1764
+ const setup = buildOpentypeSetupFromState(state, mapping);
1736
1765
  if (setup === null) return null;
1737
1766
  setCachedSystemOpentypeSetup(key, setup);
1738
1767
  return setup;
@@ -1920,7 +1949,8 @@ __export(index_exports, {
1920
1949
  getMappedFont: () => getMappedFont,
1921
1950
  getWarningEntries: () => getWarningEntries,
1922
1951
  getWarningSummary: () => getWarningSummary,
1923
- initResvgWasm: () => initResvgWasm2
1952
+ initResvgWasm: () => initResvgWasm2,
1953
+ renderPptxSourceModelToSvg: () => renderPptxSourceModelToSvg2
1924
1954
  });
1925
1955
  module.exports = __toCommonJS(index_exports);
1926
1956
 
@@ -1928,6 +1958,98 @@ module.exports = __toCommonJS(index_exports);
1928
1958
  init_font_metrics();
1929
1959
  init_cjk_font_fallback();
1930
1960
 
1961
+ // ../renderer/src/renderer/render-context.ts
1962
+ init_font_mapping();
1963
+ init_font_mapping_context();
1964
+
1965
+ // ../renderer/src/font/font-usage-collector.ts
1966
+ var FontUsageCollector = class {
1967
+ /** key: font name at the beginning of tspan's font-family list (= name declared with @font-face) */
1968
+ usages = /* @__PURE__ */ new Map();
1969
+ record(fonts, text) {
1970
+ const primary = fonts.find((f) => f !== null && f !== void 0);
1971
+ if (!primary || text.length === 0) return;
1972
+ let usage = this.usages.get(primary);
1973
+ if (!usage) {
1974
+ usage = { fonts: [...fonts], chars: /* @__PURE__ */ new Set() };
1975
+ this.usages.set(primary, usage);
1976
+ }
1977
+ for (const char of text) {
1978
+ usage.chars.add(char);
1979
+ }
1980
+ }
1981
+ getUsages() {
1982
+ return this.usages;
1983
+ }
1984
+ reset() {
1985
+ this.usages.clear();
1986
+ }
1987
+ };
1988
+ var currentCollector = null;
1989
+ function getFontUsageCollector() {
1990
+ return currentCollector;
1991
+ }
1992
+
1993
+ // ../renderer/src/font/script-font-context.ts
1994
+ var jpanMajorFont = null;
1995
+ var jpanMinorFont = null;
1996
+ function getScriptFonts() {
1997
+ return { majorJpan: jpanMajorFont, minorJpan: jpanMinorFont };
1998
+ }
1999
+ function getJpanFallbackFont() {
2000
+ return jpanMajorFont ?? jpanMinorFont;
2001
+ }
2002
+
2003
+ // ../renderer/src/font/text-measurer.ts
2004
+ init_text_measure();
2005
+ var DefaultTextMeasurer = class {
2006
+ measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa, _context) {
2007
+ return measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa);
2008
+ }
2009
+ getLineHeightRatio(fontFamily, fontFamilyEa, _context) {
2010
+ return getLineHeightRatio(fontFamily, fontFamilyEa);
2011
+ }
2012
+ getAscenderRatio(fontFamily, fontFamilyEa, _context) {
2013
+ return getAscenderRatio(fontFamily, fontFamilyEa);
2014
+ }
2015
+ };
2016
+ var currentMeasurer = new DefaultTextMeasurer();
2017
+ function getTextMeasurer() {
2018
+ return currentMeasurer;
2019
+ }
2020
+
2021
+ // ../renderer/src/renderer/render-context.ts
2022
+ init_text_path_context();
2023
+ init_warning_logger();
2024
+ function createRendererContext(overrides = {}) {
2025
+ return {
2026
+ textMeasurer: overrides.textMeasurer ?? new DefaultTextMeasurer(),
2027
+ textPathFontResolver: overrides.textPathFontResolver ?? null,
2028
+ fontMapping: overrides.fontMapping ?? { ...DEFAULT_FONT_MAPPING },
2029
+ fontUsageCollector: overrides.fontUsageCollector ?? null,
2030
+ scriptFonts: overrides.scriptFonts ?? { majorJpan: null, minorJpan: null },
2031
+ warningLogger: overrides.warningLogger ?? createWarningLogger("off"),
2032
+ fontWarningCache: overrides.fontWarningCache ?? /* @__PURE__ */ new Set()
2033
+ };
2034
+ }
2035
+ function createLegacyRendererContext() {
2036
+ return {
2037
+ textMeasurer: getTextMeasurer(),
2038
+ textPathFontResolver: getTextPathFontResolver(),
2039
+ fontMapping: getFontMapping(),
2040
+ fontUsageCollector: getFontUsageCollector(),
2041
+ scriptFonts: getScriptFonts(),
2042
+ warningLogger: getActiveWarningLogger(),
2043
+ fontWarningCache: /* @__PURE__ */ new Set()
2044
+ };
2045
+ }
2046
+ function getJpanFallbackFontFromContext(context) {
2047
+ return context.scriptFonts.majorJpan ?? context.scriptFonts.minorJpan;
2048
+ }
2049
+ function getMappedFontFromContext(fontFamily, context) {
2050
+ return getMappedFont(fontFamily, context.fontMapping);
2051
+ }
2052
+
1931
2053
  // ../renderer/src/utils/base64.ts
1932
2054
  function uint8ArrayToBase64(data) {
1933
2055
  let binary = "";
@@ -1952,7 +2074,7 @@ function glyphName(glyph, firstUnicode) {
1952
2074
  if (glyph.name) return glyph.name;
1953
2075
  return `uni${firstUnicode.toString(16).toUpperCase().padStart(4, "0")}`;
1954
2076
  }
1955
- async function subsetFont(font, chars, familyName) {
2077
+ async function subsetFont(font, chars, familyName, warningLogger) {
1956
2078
  const opentype = await tryLoadOpentypeCtors();
1957
2079
  if (!opentype) return null;
1958
2080
  const source = unsafeExternalInteropAssertion(font);
@@ -2008,44 +2130,32 @@ async function subsetFont(font, chars, familyName) {
2008
2130
  });
2009
2131
  return new Uint8Array(subset.toArrayBuffer());
2010
2132
  } catch (e) {
2011
- warn(
2012
- "font.subsetFailed",
2013
- `Failed to subset font "${familyName}": ${e instanceof Error ? e.message : String(e)}`
2014
- );
2133
+ const message = `Failed to subset font "${familyName}": ${e instanceof Error ? e.message : String(e)}`;
2134
+ if (warningLogger) {
2135
+ warningLogger.warn("font.subsetFailed", message);
2136
+ } else {
2137
+ warn("font.subsetFailed", message);
2138
+ }
2015
2139
  return null;
2016
2140
  }
2017
2141
  }
2018
2142
 
2019
- // ../renderer/src/font/script-font-context.ts
2020
- var jpanMajorFont = null;
2021
- var jpanMinorFont = null;
2022
- function setScriptFonts(majorJpan, minorJpan) {
2023
- jpanMajorFont = majorJpan;
2024
- jpanMinorFont = minorJpan;
2025
- }
2026
- function resetScriptFonts() {
2027
- jpanMajorFont = null;
2028
- jpanMinorFont = null;
2029
- }
2030
- function getJpanFallbackFont() {
2031
- return jpanMajorFont ?? jpanMinorFont;
2032
- }
2033
-
2034
2143
  // ../renderer/src/font/font-embedder.ts
2035
2144
  function escapeCssFamilyName(name) {
2036
2145
  return name.replace(/[\\"]/g, (c) => `\\${c}`).replace(/[<>&]/g, (c) => `\\${c.codePointAt(0).toString(16)} `);
2037
2146
  }
2038
- async function buildFontFaceStyle(usages, fontResolver) {
2147
+ async function buildFontFaceStyle(usages, fontResolver, context) {
2039
2148
  const faces = [];
2040
- const jpanFallback = getJpanFallbackFont();
2149
+ const jpanFallback = context !== void 0 ? getJpanFallbackFontFromContext(context) : getJpanFallbackFont();
2041
2150
  for (const [familyName, usage] of usages) {
2042
2151
  const font = fontResolver.resolveFont(
2043
2152
  usage.fonts[0],
2044
2153
  usage.fonts[1] ?? null,
2045
- usage.fonts[2] ?? jpanFallback
2154
+ usage.fonts[2] ?? jpanFallback,
2155
+ context
2046
2156
  );
2047
2157
  if (!font) continue;
2048
- const buffer = await subsetFont(font, usage.chars, familyName);
2158
+ const buffer = await subsetFont(font, usage.chars, familyName, context?.warningLogger);
2049
2159
  if (!buffer) continue;
2050
2160
  const base64 = uint8ArrayToBase64(buffer);
2051
2161
  faces.push(
@@ -2059,70 +2169,8 @@ async function buildFontFaceStyle(usages, fontResolver) {
2059
2169
  // ../renderer/src/index.ts
2060
2170
  init_font_mapping();
2061
2171
  init_font_mapping_context();
2062
-
2063
- // ../renderer/src/font/font-usage-collector.ts
2064
- var FontUsageCollector = class {
2065
- /** key: font name at the beginning of tspan's font-family list (= name declared with @font-face) */
2066
- usages = /* @__PURE__ */ new Map();
2067
- record(fonts, text) {
2068
- const primary = fonts.find((f) => f !== null && f !== void 0);
2069
- if (!primary || text.length === 0) return;
2070
- let usage = this.usages.get(primary);
2071
- if (!usage) {
2072
- usage = { fonts: [...fonts], chars: /* @__PURE__ */ new Set() };
2073
- this.usages.set(primary, usage);
2074
- }
2075
- for (const char of text) {
2076
- usage.chars.add(char);
2077
- }
2078
- }
2079
- getUsages() {
2080
- return this.usages;
2081
- }
2082
- reset() {
2083
- this.usages.clear();
2084
- }
2085
- };
2086
- var currentCollector = null;
2087
- function setFontUsageCollector(collector) {
2088
- currentCollector = collector;
2089
- }
2090
- function getFontUsageCollector() {
2091
- return currentCollector;
2092
- }
2093
- function resetFontUsageCollector() {
2094
- currentCollector = null;
2095
- }
2096
-
2097
- // ../renderer/src/index.ts
2098
2172
  init_opentype_buffer_helpers();
2099
2173
  init_opentype_text_measurer();
2100
-
2101
- // ../renderer/src/font/text-measurer.ts
2102
- init_text_measure();
2103
- var DefaultTextMeasurer = class {
2104
- measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa) {
2105
- return measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa);
2106
- }
2107
- getLineHeightRatio(fontFamily, fontFamilyEa) {
2108
- return getLineHeightRatio(fontFamily, fontFamilyEa);
2109
- }
2110
- getAscenderRatio(fontFamily, fontFamilyEa) {
2111
- return getAscenderRatio(fontFamily, fontFamilyEa);
2112
- }
2113
- };
2114
- var currentMeasurer = new DefaultTextMeasurer();
2115
- function setTextMeasurer(measurer) {
2116
- currentMeasurer = measurer;
2117
- }
2118
- function getTextMeasurer() {
2119
- return currentMeasurer;
2120
- }
2121
- function resetTextMeasurer() {
2122
- currentMeasurer = new DefaultTextMeasurer();
2123
- }
2124
-
2125
- // ../renderer/src/index.ts
2126
2174
  init_text_path_context();
2127
2175
  init_ttc_parser();
2128
2176
 
@@ -2246,9 +2294,6 @@ function round(n) {
2246
2294
  return Math.round(n * 1e3) / 1e3;
2247
2295
  }
2248
2296
 
2249
- // ../renderer/src/renderer/chart-renderer.ts
2250
- init_warning_logger();
2251
-
2252
2297
  // ../renderer/src/renderer/transform.ts
2253
2298
  function buildTransformAttr(t) {
2254
2299
  const x = emuToPixels(t.offsetX);
@@ -2279,7 +2324,7 @@ var DEFAULT_SERIES_COLORS = [
2279
2324
  { hex: "#70AD47", alpha: 1 }
2280
2325
  ];
2281
2326
  var LEGEND_SIDE_WIDTH = 100;
2282
- function renderChart(element) {
2327
+ function renderChart(element, context = createLegacyRendererContext()) {
2283
2328
  const { transform, chart } = element;
2284
2329
  const w = emuToPixels(transform.extentWidth);
2285
2330
  const h = emuToPixels(transform.extentHeight);
@@ -2307,37 +2352,37 @@ function renderChart(element) {
2307
2352
  if (plotW > 0 && plotH > 0) {
2308
2353
  switch (chart.chartType) {
2309
2354
  case "bar":
2310
- parts.push(renderBarChart(chart, plotX, plotY, plotW, plotH));
2355
+ parts.push(renderBarChart(chart, plotX, plotY, plotW, plotH, context));
2311
2356
  break;
2312
2357
  case "line":
2313
- parts.push(renderLineChart(chart, plotX, plotY, plotW, plotH));
2358
+ parts.push(renderLineChart(chart, plotX, plotY, plotW, plotH, context));
2314
2359
  break;
2315
2360
  case "pie":
2316
- parts.push(renderPieChart(chart, plotX, plotY, plotW, plotH));
2361
+ parts.push(renderPieChart(chart, plotX, plotY, plotW, plotH, context));
2317
2362
  break;
2318
2363
  case "doughnut":
2319
- parts.push(renderDoughnutChart(chart, plotX, plotY, plotW, plotH));
2364
+ parts.push(renderDoughnutChart(chart, plotX, plotY, plotW, plotH, context));
2320
2365
  break;
2321
2366
  case "scatter":
2322
- parts.push(renderScatterChart(chart, plotX, plotY, plotW, plotH));
2367
+ parts.push(renderScatterChart(chart, plotX, plotY, plotW, plotH, context));
2323
2368
  break;
2324
2369
  case "bubble":
2325
- parts.push(renderBubbleChart(chart, plotX, plotY, plotW, plotH));
2370
+ parts.push(renderBubbleChart(chart, plotX, plotY, plotW, plotH, context));
2326
2371
  break;
2327
2372
  case "area":
2328
- parts.push(renderAreaChart(chart, plotX, plotY, plotW, plotH));
2373
+ parts.push(renderAreaChart(chart, plotX, plotY, plotW, plotH, context));
2329
2374
  break;
2330
2375
  case "radar":
2331
- parts.push(renderRadarChart(chart, plotX, plotY, plotW, plotH));
2376
+ parts.push(renderRadarChart(chart, plotX, plotY, plotW, plotH, context));
2332
2377
  break;
2333
2378
  case "stock":
2334
- parts.push(renderStockChart(chart, plotX, plotY, plotW, plotH));
2379
+ parts.push(renderStockChart(chart, plotX, plotY, plotW, plotH, context));
2335
2380
  break;
2336
2381
  case "surface":
2337
- parts.push(renderSurfaceChart(chart, plotX, plotY, plotW, plotH));
2382
+ parts.push(renderSurfaceChart(chart, plotX, plotY, plotW, plotH, context));
2338
2383
  break;
2339
2384
  case "ofPie":
2340
- parts.push(renderOfPieChart(chart, plotX, plotY, plotW, plotH));
2385
+ parts.push(renderOfPieChart(chart, plotX, plotY, plotW, plotH, context));
2341
2386
  break;
2342
2387
  }
2343
2388
  }
@@ -2350,21 +2395,24 @@ function renderChart(element) {
2350
2395
  function renderChartTitle(title, chartWidth) {
2351
2396
  return `<text x="${round2(chartWidth / 2)}" y="20" text-anchor="middle" font-size="14" font-weight="bold" fill="#404040">${escapeXml(title)}</text>`;
2352
2397
  }
2353
- function renderBarChart(chart, x, y, w, h) {
2398
+ function debugChart(context, feature, message) {
2399
+ context.warningLogger.debug(feature, message);
2400
+ }
2401
+ function renderBarChart(chart, x, y, w, h, context) {
2354
2402
  const parts = [];
2355
2403
  const { series, categories } = chart;
2356
2404
  if (series.length === 0) {
2357
- debug("chart.bar", "series is empty");
2405
+ debugChart(context, "chart.bar", "series is empty");
2358
2406
  return "";
2359
2407
  }
2360
2408
  const maxVal = getMaxValue(series);
2361
2409
  if (maxVal === 0) {
2362
- debug("chart.bar", "max value is 0");
2410
+ debugChart(context, "chart.bar", "max value is 0");
2363
2411
  return "";
2364
2412
  }
2365
2413
  const catCount = categories.length || Math.max(...series.map((s) => s.values.length));
2366
2414
  if (catCount === 0) {
2367
- debug("chart.bar", "category count is 0");
2415
+ debugChart(context, "chart.bar", "category count is 0");
2368
2416
  return "";
2369
2417
  }
2370
2418
  const isHorizontal = chart.barDirection === "bar";
@@ -2437,21 +2485,21 @@ function renderBarChart(chart, x, y, w, h) {
2437
2485
  }
2438
2486
  return parts.join("");
2439
2487
  }
2440
- function renderLineChart(chart, x, y, w, h) {
2488
+ function renderLineChart(chart, x, y, w, h, context) {
2441
2489
  const parts = [];
2442
2490
  const { series, categories } = chart;
2443
2491
  if (series.length === 0) {
2444
- debug("chart.line", "series is empty");
2492
+ debugChart(context, "chart.line", "series is empty");
2445
2493
  return "";
2446
2494
  }
2447
2495
  const maxVal = getMaxValue(series);
2448
2496
  if (maxVal === 0) {
2449
- debug("chart.line", "max value is 0");
2497
+ debugChart(context, "chart.line", "max value is 0");
2450
2498
  return "";
2451
2499
  }
2452
2500
  const catCount = categories.length || Math.max(...series.map((s) => s.values.length));
2453
2501
  if (catCount === 0) {
2454
- debug("chart.line", "category count is 0");
2502
+ debugChart(context, "chart.line", "category count is 0");
2455
2503
  return "";
2456
2504
  }
2457
2505
  const ticks = computeNiceTicks(0, maxVal);
@@ -2489,21 +2537,21 @@ function renderLineChart(chart, x, y, w, h) {
2489
2537
  }
2490
2538
  return parts.join("");
2491
2539
  }
2492
- function renderAreaChart(chart, x, y, w, h) {
2540
+ function renderAreaChart(chart, x, y, w, h, context) {
2493
2541
  const parts = [];
2494
2542
  const { series, categories } = chart;
2495
2543
  if (series.length === 0) {
2496
- debug("chart.area", "series is empty");
2544
+ debugChart(context, "chart.area", "series is empty");
2497
2545
  return "";
2498
2546
  }
2499
2547
  const maxVal = getMaxValue(series);
2500
2548
  if (maxVal === 0) {
2501
- debug("chart.area", "max value is 0");
2549
+ debugChart(context, "chart.area", "max value is 0");
2502
2550
  return "";
2503
2551
  }
2504
2552
  const catCount = categories.length || Math.max(...series.map((s) => s.values.length));
2505
2553
  if (catCount === 0) {
2506
- debug("chart.area", "category count is 0");
2554
+ debugChart(context, "chart.area", "category count is 0");
2507
2555
  return "";
2508
2556
  }
2509
2557
  const ticks = computeNiceTicks(0, maxVal);
@@ -2542,16 +2590,16 @@ function renderAreaChart(chart, x, y, w, h) {
2542
2590
  }
2543
2591
  return parts.join("");
2544
2592
  }
2545
- function renderPieChart(chart, x, y, w, h) {
2593
+ function renderPieChart(chart, x, y, w, h, context) {
2546
2594
  const parts = [];
2547
2595
  const series = chart.series[0];
2548
2596
  if (!series || series.values.length === 0) {
2549
- debug("chart.pie", "series is empty or has no values");
2597
+ debugChart(context, "chart.pie", "series is empty or has no values");
2550
2598
  return "";
2551
2599
  }
2552
2600
  const total = series.values.reduce((sum, v) => sum + v, 0);
2553
2601
  if (total === 0) {
2554
- debug("chart.pie", "total value is 0");
2602
+ debugChart(context, "chart.pie", "total value is 0");
2555
2603
  return "";
2556
2604
  }
2557
2605
  const cx = x + w / 2;
@@ -2580,16 +2628,16 @@ function renderPieChart(chart, x, y, w, h) {
2580
2628
  }
2581
2629
  return parts.join("");
2582
2630
  }
2583
- function renderDoughnutChart(chart, x, y, w, h) {
2631
+ function renderDoughnutChart(chart, x, y, w, h, context) {
2584
2632
  const parts = [];
2585
2633
  const series = chart.series[0];
2586
2634
  if (!series || series.values.length === 0) {
2587
- debug("chart.doughnut", "series is empty or has no values");
2635
+ debugChart(context, "chart.doughnut", "series is empty or has no values");
2588
2636
  return "";
2589
2637
  }
2590
2638
  const total = series.values.reduce((sum, v) => sum + v, 0);
2591
2639
  if (total === 0) {
2592
- debug("chart.doughnut", "total value is 0");
2640
+ debugChart(context, "chart.doughnut", "total value is 0");
2593
2641
  return "";
2594
2642
  }
2595
2643
  const cx = x + w / 2;
@@ -2627,11 +2675,11 @@ function renderDoughnutChart(chart, x, y, w, h) {
2627
2675
  }
2628
2676
  return parts.join("");
2629
2677
  }
2630
- function renderScatterChart(chart, x, y, w, h) {
2678
+ function renderScatterChart(chart, x, y, w, h, context) {
2631
2679
  const parts = [];
2632
2680
  const { series } = chart;
2633
2681
  if (series.length === 0) {
2634
- debug("chart.scatter", "series is empty");
2682
+ debugChart(context, "chart.scatter", "series is empty");
2635
2683
  return "";
2636
2684
  }
2637
2685
  let maxX = 0;
@@ -2665,11 +2713,11 @@ function renderScatterChart(chart, x, y, w, h) {
2665
2713
  }
2666
2714
  return parts.join("");
2667
2715
  }
2668
- function renderBubbleChart(chart, x, y, w, h) {
2716
+ function renderBubbleChart(chart, x, y, w, h, context) {
2669
2717
  const parts = [];
2670
2718
  const { series } = chart;
2671
2719
  if (series.length === 0) {
2672
- debug("chart.bubble", "series is empty");
2720
+ debugChart(context, "chart.bubble", "series is empty");
2673
2721
  return "";
2674
2722
  }
2675
2723
  let maxX = 0;
@@ -2713,21 +2761,21 @@ function renderBubbleChart(chart, x, y, w, h) {
2713
2761
  }
2714
2762
  return parts.join("");
2715
2763
  }
2716
- function renderRadarChart(chart, x, y, w, h) {
2764
+ function renderRadarChart(chart, x, y, w, h, context) {
2717
2765
  const parts = [];
2718
2766
  const { series, categories } = chart;
2719
2767
  if (series.length === 0) {
2720
- debug("chart.radar", "series is empty");
2768
+ debugChart(context, "chart.radar", "series is empty");
2721
2769
  return "";
2722
2770
  }
2723
2771
  const maxVal = getMaxValue(series);
2724
2772
  if (maxVal === 0) {
2725
- debug("chart.radar", "max value is 0");
2773
+ debugChart(context, "chart.radar", "max value is 0");
2726
2774
  return "";
2727
2775
  }
2728
2776
  const catCount = categories.length || Math.max(...series.map((s) => s.values.length));
2729
2777
  if (catCount === 0) {
2730
- debug("chart.radar", "category count is 0");
2778
+ debugChart(context, "chart.radar", "category count is 0");
2731
2779
  return "";
2732
2780
  }
2733
2781
  const cx = x + w / 2;
@@ -2790,11 +2838,15 @@ function renderRadarChart(chart, x, y, w, h) {
2790
2838
  }
2791
2839
  return parts.join("");
2792
2840
  }
2793
- function renderStockChart(chart, x, y, w, h) {
2841
+ function renderStockChart(chart, x, y, w, h, context) {
2794
2842
  const parts = [];
2795
2843
  const { series, categories } = chart;
2796
2844
  if (series.length < 3) {
2797
- debug("chart.stock", `insufficient series count: ${series.length} (need at least 3)`);
2845
+ debugChart(
2846
+ context,
2847
+ "chart.stock",
2848
+ `insufficient series count: ${series.length} (need at least 3)`
2849
+ );
2798
2850
  return "";
2799
2851
  }
2800
2852
  const highSeries = series[0];
@@ -2802,7 +2854,7 @@ function renderStockChart(chart, x, y, w, h) {
2802
2854
  const closeSeries = series[2];
2803
2855
  const catCount = categories.length || highSeries.values.length;
2804
2856
  if (catCount === 0) {
2805
- debug("chart.stock", "category count is 0");
2857
+ debugChart(context, "chart.stock", "category count is 0");
2806
2858
  return "";
2807
2859
  }
2808
2860
  let maxVal = 0;
@@ -2814,7 +2866,7 @@ function renderStockChart(chart, x, y, w, h) {
2814
2866
  }
2815
2867
  }
2816
2868
  if (maxVal === minVal) {
2817
- debug("chart.stock", "max equals min value");
2869
+ debugChart(context, "chart.stock", "max equals min value");
2818
2870
  return "";
2819
2871
  }
2820
2872
  const ticks = computeNiceTicks(minVal, maxVal);
@@ -2853,17 +2905,17 @@ function renderStockChart(chart, x, y, w, h) {
2853
2905
  }
2854
2906
  return parts.join("");
2855
2907
  }
2856
- function renderSurfaceChart(chart, x, y, w, h) {
2908
+ function renderSurfaceChart(chart, x, y, w, h, context) {
2857
2909
  const parts = [];
2858
2910
  const { series, categories } = chart;
2859
2911
  if (series.length === 0) {
2860
- debug("chart.surface", "series is empty");
2912
+ debugChart(context, "chart.surface", "series is empty");
2861
2913
  return "";
2862
2914
  }
2863
2915
  const rows = series.length;
2864
2916
  const cols = categories.length || Math.max(...series.map((s) => s.values.length));
2865
2917
  if (cols === 0) {
2866
- debug("chart.surface", "column count is 0");
2918
+ debugChart(context, "chart.surface", "column count is 0");
2867
2919
  return "";
2868
2920
  }
2869
2921
  let minVal = Infinity;
@@ -2935,16 +2987,16 @@ function heatmapColor(t) {
2935
2987
  }
2936
2988
  return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
2937
2989
  }
2938
- function renderOfPieChart(chart, x, y, w, h) {
2990
+ function renderOfPieChart(chart, x, y, w, h, context) {
2939
2991
  const parts = [];
2940
2992
  const series = chart.series[0];
2941
2993
  if (!series || series.values.length === 0) {
2942
- debug("chart.ofPie", "series is empty or has no values");
2994
+ debugChart(context, "chart.ofPie", "series is empty or has no values");
2943
2995
  return "";
2944
2996
  }
2945
2997
  const total = series.values.reduce((sum, v) => sum + v, 0);
2946
2998
  if (total === 0) {
2947
- debug("chart.ofPie", "total value is 0");
2999
+ debugChart(context, "chart.ofPie", "total value is 0");
2948
3000
  return "";
2949
3001
  }
2950
3002
  const splitPos = chart.splitPos ?? 2;
@@ -3045,40 +3097,40 @@ function renderOfPieChart(chart, x, y, w, h) {
3045
3097
  }
3046
3098
  function renderLegend(chart, chartW, chartH, position) {
3047
3099
  const parts = [];
3048
- const entries2 = chart.chartType === "pie" || chart.chartType === "doughnut" || chart.chartType === "ofPie" ? chart.categories.map((cat, i) => ({
3100
+ const entries = chart.chartType === "pie" || chart.chartType === "doughnut" || chart.chartType === "ofPie" ? chart.categories.map((cat, i) => ({
3049
3101
  label: cat,
3050
3102
  color: getPieSliceColor(i, chart)
3051
3103
  })) : chart.series.map((s, i) => ({
3052
3104
  label: s.name ?? `Series ${i + 1}`,
3053
3105
  color: s.color
3054
3106
  }));
3055
- if (entries2.length === 0) return "";
3107
+ if (entries.length === 0) return "";
3056
3108
  const ENTRY_HEIGHT = 20;
3057
3109
  if (position === "r" || position === "l") {
3058
- const totalH = entries2.length * ENTRY_HEIGHT;
3110
+ const totalH = entries.length * ENTRY_HEIGHT;
3059
3111
  const startY = Math.max((chartH - totalH) / 2, 5);
3060
3112
  const legendX = position === "r" ? chartW - LEGEND_SIDE_WIDTH + 5 : 5;
3061
- for (let i = 0; i < entries2.length; i++) {
3113
+ for (let i = 0; i < entries.length; i++) {
3062
3114
  const ey = startY + i * ENTRY_HEIGHT;
3063
3115
  parts.push(
3064
- `<rect x="${round2(legendX)}" y="${round2(ey)}" width="12" height="12" ${fillAttr(entries2[i].color)}/>`
3116
+ `<rect x="${round2(legendX)}" y="${round2(ey)}" width="12" height="12" ${fillAttr(entries[i].color)}/>`
3065
3117
  );
3066
3118
  parts.push(
3067
- `<text x="${round2(legendX + 16)}" y="${round2(ey + 10)}" font-size="10" fill="#595959">${escapeXml(entries2[i].label)}</text>`
3119
+ `<text x="${round2(legendX + 16)}" y="${round2(ey + 10)}" font-size="10" fill="#595959">${escapeXml(entries[i].label)}</text>`
3068
3120
  );
3069
3121
  }
3070
3122
  } else {
3071
3123
  const entryWidth = 80;
3072
- const totalWidth = entries2.length * entryWidth;
3124
+ const totalWidth = entries.length * entryWidth;
3073
3125
  const startX = Math.max((chartW - totalWidth) / 2, 5);
3074
3126
  const legendY = position === "t" ? 25 : chartH - 15;
3075
- for (let i = 0; i < entries2.length; i++) {
3127
+ for (let i = 0; i < entries.length; i++) {
3076
3128
  const ex = startX + i * entryWidth;
3077
3129
  parts.push(
3078
- `<rect x="${round2(ex)}" y="${round2(legendY - 6)}" width="12" height="12" ${fillAttr(entries2[i].color)}/>`
3130
+ `<rect x="${round2(ex)}" y="${round2(legendY - 6)}" width="12" height="12" ${fillAttr(entries[i].color)}/>`
3079
3131
  );
3080
3132
  parts.push(
3081
- `<text x="${round2(ex + 16)}" y="${round2(legendY + 4)}" font-size="10" fill="#595959">${escapeXml(entries2[i].label)}</text>`
3133
+ `<text x="${round2(ex + 16)}" y="${round2(legendY + 4)}" font-size="10" fill="#595959">${escapeXml(entries[i].label)}</text>`
3082
3134
  );
3083
3135
  }
3084
3136
  }
@@ -4424,8 +4476,6 @@ function renderCustomPath(path, shapeWidth, shapeHeight) {
4424
4476
 
4425
4477
  // ../renderer/src/renderer/text-renderer.ts
4426
4478
  init_font_metrics();
4427
- init_font_mapping_context();
4428
- init_text_path_context();
4429
4479
 
4430
4480
  // ../renderer/src/utils/text-wrap.ts
4431
4481
  var DEFAULT_FONT_SIZE = 18;
@@ -4477,7 +4527,7 @@ function splitTextIntoFragments(text) {
4477
4527
  }
4478
4528
  return fragments;
4479
4529
  }
4480
- function tokenizeRuns(runs, defaultFontSize, fontScale) {
4530
+ function tokenizeRuns(runs, defaultFontSize, fontScale, textMeasurer, measurementContext) {
4481
4531
  const tokens = [];
4482
4532
  let isFirst = true;
4483
4533
  for (const run of runs) {
@@ -4503,12 +4553,13 @@ function tokenizeRuns(runs, defaultFontSize, fontScale) {
4503
4553
  const fontFamilyEa2 = run.properties.fontFamilyEa;
4504
4554
  const fragments2 = splitTextIntoFragments(part);
4505
4555
  for (const { fragment, breakable } of fragments2) {
4506
- const width = getTextMeasurer().measureTextWidth(
4556
+ const width = textMeasurer.measureTextWidth(
4507
4557
  fragment,
4508
4558
  fontSize2,
4509
4559
  bold2,
4510
4560
  fontFamily2,
4511
- fontFamilyEa2
4561
+ fontFamilyEa2,
4562
+ measurementContext
4512
4563
  );
4513
4564
  tokens.push({
4514
4565
  text: fragment,
@@ -4527,12 +4578,13 @@ function tokenizeRuns(runs, defaultFontSize, fontScale) {
4527
4578
  const fontFamilyEa = run.properties.fontFamilyEa;
4528
4579
  const fragments = splitTextIntoFragments(run.text);
4529
4580
  for (const { fragment, breakable } of fragments) {
4530
- const width = getTextMeasurer().measureTextWidth(
4581
+ const width = textMeasurer.measureTextWidth(
4531
4582
  fragment,
4532
4583
  fontSize,
4533
4584
  bold,
4534
4585
  fontFamily,
4535
- fontFamilyEa
4586
+ fontFamilyEa,
4587
+ measurementContext
4536
4588
  );
4537
4589
  tokens.push({
4538
4590
  text: fragment,
@@ -4551,7 +4603,7 @@ function isSpaceOnly(text) {
4551
4603
  }
4552
4604
  return true;
4553
4605
  }
4554
- function splitTokenByChars(token, availableWidth, defaultFontSize, fontScale) {
4606
+ function splitTokenByChars(token, availableWidth, defaultFontSize, fontScale, textMeasurer, measurementContext) {
4555
4607
  const lines = [];
4556
4608
  let currentLine = [];
4557
4609
  let currentWidth = 0;
@@ -4560,12 +4612,13 @@ function splitTokenByChars(token, availableWidth, defaultFontSize, fontScale) {
4560
4612
  const fontFamily = token.properties.fontFamily;
4561
4613
  const fontFamilyEa = token.properties.fontFamilyEa;
4562
4614
  for (const char of token.text) {
4563
- const charWidth = getTextMeasurer().measureTextWidth(
4615
+ const charWidth = textMeasurer.measureTextWidth(
4564
4616
  char,
4565
4617
  fontSize,
4566
4618
  bold,
4567
4619
  fontFamily,
4568
- fontFamilyEa
4620
+ fontFamilyEa,
4621
+ measurementContext
4569
4622
  );
4570
4623
  if (currentWidth + charWidth > availableWidth && currentLine.length > 0) {
4571
4624
  lines.push(currentLine);
@@ -4612,7 +4665,7 @@ function trimTrailingSpaces(segments) {
4612
4665
  }
4613
4666
  return segments;
4614
4667
  }
4615
- function layoutTokensIntoLines(tokens, availableWidth, defaultFontSize, fontScale) {
4668
+ function layoutTokensIntoLines(tokens, availableWidth, defaultFontSize, fontScale, textMeasurer, measurementContext) {
4616
4669
  if (tokens.length === 0) return [{ segments: [] }];
4617
4670
  const lines = [];
4618
4671
  let currentLine = [];
@@ -4634,7 +4687,14 @@ function layoutTokensIntoLines(tokens, availableWidth, defaultFontSize, fontScal
4634
4687
  if (isSpaceOnly(token.text)) {
4635
4688
  continue;
4636
4689
  }
4637
- const splitLines = splitTokenByChars(token, availableWidth, defaultFontSize, fontScale);
4690
+ const splitLines = splitTokenByChars(
4691
+ token,
4692
+ availableWidth,
4693
+ defaultFontSize,
4694
+ fontScale,
4695
+ textMeasurer,
4696
+ measurementContext
4697
+ );
4638
4698
  for (let j = 0; j < splitLines.length; j++) {
4639
4699
  if (j < splitLines.length - 1) {
4640
4700
  const segments = trimTrailingSpaces(mergeSegments(splitLines[j]));
@@ -4667,14 +4727,27 @@ function layoutTokensIntoLines(tokens, availableWidth, defaultFontSize, fontScal
4667
4727
  }
4668
4728
  return lines.length > 0 ? lines : [{ segments: [] }];
4669
4729
  }
4670
- function wrapParagraph(paragraph, availableWidth, defaultFontSize = DEFAULT_FONT_SIZE, fontScale = 1) {
4730
+ function wrapParagraph(paragraph, availableWidth, defaultFontSize = DEFAULT_FONT_SIZE, fontScale = 1, textMeasurer = getTextMeasurer(), measurementContext) {
4671
4731
  if (paragraph.runs.length === 0 || !paragraph.runs.some((r) => r.text.length > 0)) {
4672
4732
  return [{ segments: [] }];
4673
4733
  }
4674
4734
  const safeWidth = Math.max(availableWidth, 1);
4675
- const tokens = tokenizeRuns(paragraph.runs, defaultFontSize, fontScale);
4735
+ const tokens = tokenizeRuns(
4736
+ paragraph.runs,
4737
+ defaultFontSize,
4738
+ fontScale,
4739
+ textMeasurer,
4740
+ measurementContext
4741
+ );
4676
4742
  if (tokens.length === 0) return [{ segments: [] }];
4677
- return layoutTokensIntoLines(tokens, safeWidth, defaultFontSize, fontScale);
4743
+ return layoutTokensIntoLines(
4744
+ tokens,
4745
+ safeWidth,
4746
+ defaultFontSize,
4747
+ fontScale,
4748
+ textMeasurer,
4749
+ measurementContext
4750
+ );
4678
4751
  }
4679
4752
 
4680
4753
  // ../renderer/src/utils/unit-types.ts
@@ -4727,10 +4800,10 @@ function resolveTextDimensions(bodyProperties, originalWidth, originalHeight) {
4727
4800
  marginBottomPx: emuToPixels(bodyProperties.marginBottom)
4728
4801
  };
4729
4802
  }
4730
- function renderTextBody(textBody, transform) {
4731
- const fontResolver = getTextPathFontResolver();
4803
+ function renderTextBody(textBody, transform, context = createLegacyRendererContext()) {
4804
+ const fontResolver = context.textPathFontResolver;
4732
4805
  if (fontResolver) {
4733
- return renderTextBodyAsPath(textBody, transform, fontResolver);
4806
+ return renderTextBodyAsPath(textBody, transform, fontResolver, context);
4734
4807
  }
4735
4808
  const { bodyProperties, paragraphs } = textBody;
4736
4809
  const originalWidth = emuToPixels(transform.extentWidth);
@@ -4753,12 +4826,13 @@ function renderTextBody(textBody, transform) {
4753
4826
  fontScale,
4754
4827
  lnSpcReduction,
4755
4828
  textWidth,
4756
- availableHeight
4829
+ availableHeight,
4830
+ context
4757
4831
  );
4758
4832
  }
4759
4833
  const scaledDefaultFontSizePt = defaultFontSize * fontScale;
4760
- const defaultLineHeightRatio = getDefaultLineHeightRatio(paragraphs);
4761
- const defaultAscenderRatio = getDefaultAscenderRatio(paragraphs);
4834
+ const defaultLineHeightRatio = getDefaultLineHeightRatio(paragraphs, context);
4835
+ const defaultAscenderRatio = getDefaultAscenderRatio(paragraphs, context);
4762
4836
  const defaultNaturalHeightPt = scaledDefaultFontSizePt * defaultLineHeightRatio;
4763
4837
  const tspans = [];
4764
4838
  let isFirstLine = true;
@@ -4798,7 +4872,9 @@ function renderTextBody(textBody, transform) {
4798
4872
  para,
4799
4873
  effectiveTextWidth,
4800
4874
  scaledDefaultFontSizePt,
4801
- fontScale
4875
+ fontScale,
4876
+ context.textMeasurer,
4877
+ context
4802
4878
  );
4803
4879
  for (let lineIdx = 0; lineIdx < wrappedLines.length; lineIdx++) {
4804
4880
  const line = wrappedLines[lineIdx];
@@ -4818,7 +4894,8 @@ function renderTextBody(textBody, transform) {
4818
4894
  const lineNaturalHeightPt = computeLineNaturalHeight(
4819
4895
  line.segments,
4820
4896
  defaultFontSize,
4821
- fontScale
4897
+ fontScale,
4898
+ context
4822
4899
  );
4823
4900
  const dy = computeDy(
4824
4901
  isFirstLine,
@@ -4835,16 +4912,17 @@ function renderTextBody(textBody, transform) {
4835
4912
  para.properties,
4836
4913
  lineFontSize,
4837
4914
  fontScale,
4838
- bulletFontChain
4915
+ bulletFontChain,
4916
+ context
4839
4917
  );
4840
- getFontUsageCollector()?.record(bulletFontChain, bulletText);
4918
+ context.fontUsageCollector?.record(bulletFontChain, bulletText);
4841
4919
  tspans.push(
4842
4920
  `<tspan x="${bulletX}" dy="${dy}" text-anchor="start" ${bulletStyles}>${escapeXml2(bulletText)}</tspan>`
4843
4921
  );
4844
4922
  for (let segIdx = 0; segIdx < line.segments.length; segIdx++) {
4845
4923
  const seg = line.segments[segIdx];
4846
4924
  const prefix = segIdx === 0 ? `x="${xPos}" text-anchor="${anchorValue}" ` : "";
4847
- tspans.push(renderSegment(seg.text, seg.properties, fontScale, prefix));
4925
+ tspans.push(renderSegment(seg.text, seg.properties, fontScale, prefix, context));
4848
4926
  }
4849
4927
  } else {
4850
4928
  for (let segIdx = 0; segIdx < line.segments.length; segIdx++) {
@@ -4853,7 +4931,8 @@ function renderTextBody(textBody, transform) {
4853
4931
  const lineNaturalHeightPt = computeLineNaturalHeight(
4854
4932
  line.segments,
4855
4933
  defaultFontSize,
4856
- fontScale
4934
+ fontScale,
4935
+ context
4857
4936
  );
4858
4937
  const dy = computeDy(
4859
4938
  isFirstLine,
@@ -4861,9 +4940,9 @@ function renderTextBody(textBody, transform) {
4861
4940
  lineGapPx
4862
4941
  );
4863
4942
  const prefix = `x="${xPos}" dy="${dy}" text-anchor="${anchorValue}" `;
4864
- tspans.push(renderSegment(seg.text, seg.properties, fontScale, prefix));
4943
+ tspans.push(renderSegment(seg.text, seg.properties, fontScale, prefix, context));
4865
4944
  } else {
4866
- tspans.push(renderSegment(seg.text, seg.properties, fontScale, ""));
4945
+ tspans.push(renderSegment(seg.text, seg.properties, fontScale, "", context));
4867
4946
  }
4868
4947
  }
4869
4948
  }
@@ -4874,7 +4953,12 @@ function renderTextBody(textBody, transform) {
4874
4953
  if (bulletText) {
4875
4954
  const firstRun = para.runs.find((r) => r.text.length > 0);
4876
4955
  const fontSize = (firstRun?.properties.fontSize ?? defaultFontSize) * fontScale;
4877
- const naturalHeightPt = computeLineNaturalHeight(para.runs, defaultFontSize, fontScale);
4956
+ const naturalHeightPt = computeLineNaturalHeight(
4957
+ para.runs,
4958
+ defaultFontSize,
4959
+ fontScale,
4960
+ context
4961
+ );
4878
4962
  const dy = computeDy(
4879
4963
  isFirstLine,
4880
4964
  getLineHeightPx(para, naturalHeightPt, lnSpcReduction),
@@ -4889,9 +4973,10 @@ function renderTextBody(textBody, transform) {
4889
4973
  para.properties,
4890
4974
  fontSize,
4891
4975
  fontScale,
4892
- bulletFontChain
4976
+ bulletFontChain,
4977
+ context
4893
4978
  );
4894
- getFontUsageCollector()?.record(bulletFontChain, bulletText);
4979
+ context.fontUsageCollector?.record(bulletFontChain, bulletText);
4895
4980
  tspans.push(
4896
4981
  `<tspan x="${bulletX}" dy="${dy}" text-anchor="start" ${bulletStyles}>${escapeXml2(bulletText)}</tspan>`
4897
4982
  );
@@ -4902,20 +4987,25 @@ function renderTextBody(textBody, transform) {
4902
4987
  if (!firstRunRendered) {
4903
4988
  if (bulletText) {
4904
4989
  const prefix = `x="${xPos}" text-anchor="${anchorValue}" `;
4905
- tspans.push(renderSegment(run.text, run.properties, fontScale, prefix));
4990
+ tspans.push(renderSegment(run.text, run.properties, fontScale, prefix, context));
4906
4991
  } else {
4907
- const naturalHeightPt = computeLineNaturalHeight(para.runs, defaultFontSize, fontScale);
4992
+ const naturalHeightPt = computeLineNaturalHeight(
4993
+ para.runs,
4994
+ defaultFontSize,
4995
+ fontScale,
4996
+ context
4997
+ );
4908
4998
  const dy = computeDy(
4909
4999
  isFirstLine,
4910
5000
  getLineHeightPx(para, naturalHeightPt, lnSpcReduction),
4911
5001
  paragraphGapPx
4912
5002
  );
4913
5003
  const prefix = `x="${xPos}" dy="${dy}" text-anchor="${anchorValue}" `;
4914
- tspans.push(renderSegment(run.text, run.properties, fontScale, prefix));
5004
+ tspans.push(renderSegment(run.text, run.properties, fontScale, prefix, context));
4915
5005
  }
4916
5006
  firstRunRendered = true;
4917
5007
  } else {
4918
- tspans.push(renderSegment(run.text, run.properties, fontScale, ""));
5008
+ tspans.push(renderSegment(run.text, run.properties, fontScale, "", context));
4919
5009
  }
4920
5010
  }
4921
5011
  isFirstLine = false;
@@ -4929,7 +5019,8 @@ function renderTextBody(textBody, transform) {
4929
5019
  shouldWrap,
4930
5020
  textWidth,
4931
5021
  lnSpcReduction,
4932
- fontScale
5022
+ fontScale,
5023
+ context
4933
5024
  );
4934
5025
  if (bodyProperties.anchor === "ctr") {
4935
5026
  yStart = Math.max(marginTopPx, (height - totalTextHeight) / 2);
@@ -5026,13 +5117,13 @@ function toAlpha(num) {
5026
5117
  function buildBulletFontChain(props, runFontFamily, runFontFamilyEa) {
5027
5118
  return [props.bulletFont, runFontFamily ?? null, runFontFamilyEa ?? null];
5028
5119
  }
5029
- function buildBulletStyleAttrs(props, textFontSizePt, fontScale, bulletFontChain) {
5120
+ function buildBulletStyleAttrs(props, textFontSizePt, fontScale, bulletFontChain, context = createLegacyRendererContext()) {
5030
5121
  const styles = [];
5031
5122
  if (props.bulletSizePct !== null) {
5032
5123
  const size = textFontSizePt * (props.bulletSizePct / 1e5);
5033
5124
  styles.push(`font-size="${size}pt"`);
5034
5125
  }
5035
- const fontFamilyValue = buildFontFamilyValue(bulletFontChain);
5126
+ const fontFamilyValue = buildFontFamilyValue(bulletFontChain, context);
5036
5127
  if (fontFamilyValue) {
5037
5128
  styles.push(`font-family="${fontFamilyValue}"`);
5038
5129
  }
@@ -5085,13 +5176,14 @@ function getLineFontSize(segments, defaultFontSize) {
5085
5176
  }
5086
5177
  return defaultFontSize;
5087
5178
  }
5088
- function computeLineNaturalHeight(segments, defaultFontSize, fontScale) {
5179
+ function computeLineNaturalHeight(segments, defaultFontSize, fontScale, context = createLegacyRendererContext()) {
5089
5180
  let maxHeight = 0;
5090
5181
  for (const seg of segments) {
5091
5182
  const fontSize = (seg.properties.fontSize ?? defaultFontSize) * fontScale;
5092
- const ratio = getTextMeasurer().getLineHeightRatio(
5183
+ const ratio = context.textMeasurer.getLineHeightRatio(
5093
5184
  seg.properties.fontFamily,
5094
- seg.properties.fontFamilyEa
5185
+ seg.properties.fontFamilyEa,
5186
+ context
5095
5187
  );
5096
5188
  maxHeight = Math.max(maxHeight, fontSize * ratio);
5097
5189
  }
@@ -5132,14 +5224,14 @@ function getGenericFamily(fontFamily) {
5132
5224
  function escapeFontName(name) {
5133
5225
  return name.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
5134
5226
  }
5135
- function buildFontFamilyValue(fonts) {
5227
+ function buildFontFamilyValue(fonts, context = createLegacyRendererContext()) {
5136
5228
  const uniqueFonts = [];
5137
5229
  const seen = /* @__PURE__ */ new Set();
5138
5230
  for (const font of fonts) {
5139
5231
  if (font && !seen.has(font)) {
5140
5232
  seen.add(font);
5141
5233
  uniqueFonts.push(font);
5142
- const mapped = getCurrentMappedFont(font);
5234
+ const mapped = getMappedFontFromContext(font, context);
5143
5235
  if (mapped && !seen.has(mapped)) {
5144
5236
  seen.add(mapped);
5145
5237
  uniqueFonts.push(mapped);
@@ -5160,14 +5252,14 @@ function buildFontFamilyValue(fonts) {
5160
5252
  parts.push(genericFamily);
5161
5253
  return parts.join(", ");
5162
5254
  }
5163
- function buildStyleAttrs(props, fontScale = 1, fontFamilies) {
5255
+ function buildStyleAttrs(props, fontScale = 1, fontFamilies, context = createLegacyRendererContext()) {
5164
5256
  const styles = [];
5165
5257
  if (props.fontSize) {
5166
5258
  const scaledSize = props.fontSize * fontScale;
5167
5259
  styles.push(`font-size="${scaledSize}pt"`);
5168
5260
  }
5169
5261
  const fonts = fontFamilies ?? [props.fontFamily, props.fontFamilyEa];
5170
- const fontFamilyValue = buildFontFamilyValue(fonts);
5262
+ const fontFamilyValue = buildFontFamilyValue(fonts, context);
5171
5263
  if (fontFamilyValue) {
5172
5264
  styles.push(`font-family="${fontFamilyValue}"`);
5173
5265
  }
@@ -5205,20 +5297,20 @@ function buildStyleAttrs(props, fontScale = 1, fontFamilies) {
5205
5297
  }
5206
5298
  return styles.join(" ");
5207
5299
  }
5208
- function renderSegment(text, props, fontScale, prefix) {
5300
+ function renderSegment(text, props, fontScale, prefix, context) {
5209
5301
  let tspanContent;
5210
5302
  if (!needsScriptSplit(props)) {
5211
- const styles = buildStyleAttrs(props, fontScale);
5212
- getFontUsageCollector()?.record([props.fontFamily, props.fontFamilyEa], text);
5303
+ const styles = buildStyleAttrs(props, fontScale, void 0, context);
5304
+ context.fontUsageCollector?.record([props.fontFamily, props.fontFamilyEa], text);
5213
5305
  tspanContent = `<tspan ${prefix}${styles}>${escapeXml2(text)}</tspan>`;
5214
5306
  } else {
5215
5307
  const parts = splitByScript(text);
5216
5308
  const result = [];
5217
5309
  for (let i = 0; i < parts.length; i++) {
5218
5310
  const part = parts[i];
5219
- const fonts = part.isEa ? [props.fontFamilyEa, getJpanFallbackFont(), props.fontFamily] : [props.fontFamily, props.fontFamilyEa];
5220
- const styles = buildStyleAttrs(props, fontScale, fonts);
5221
- getFontUsageCollector()?.record(fonts, part.text);
5311
+ const fonts = part.isEa ? [props.fontFamilyEa, getJpanFallbackFontFromContext(context), props.fontFamily] : [props.fontFamily, props.fontFamilyEa];
5312
+ const styles = buildStyleAttrs(props, fontScale, fonts, context);
5313
+ context.fontUsageCollector?.record(fonts, part.text);
5222
5314
  if (i === 0) {
5223
5315
  result.push(`<tspan ${prefix}${styles}>${escapeXml2(part.text)}</tspan>`);
5224
5316
  } else {
@@ -5241,33 +5333,35 @@ function getDefaultFontSize(paragraphs) {
5241
5333
  }
5242
5334
  return DEFAULT_FONT_SIZE_PT;
5243
5335
  }
5244
- function getDefaultLineHeightRatio(paragraphs) {
5336
+ function getDefaultLineHeightRatio(paragraphs, context = createLegacyRendererContext()) {
5245
5337
  for (const p of paragraphs) {
5246
5338
  for (const r of p.runs) {
5247
5339
  if (r.properties.fontFamily || r.properties.fontFamilyEa) {
5248
- return getTextMeasurer().getLineHeightRatio(
5340
+ return context.textMeasurer.getLineHeightRatio(
5249
5341
  r.properties.fontFamily,
5250
- r.properties.fontFamilyEa
5342
+ r.properties.fontFamilyEa,
5343
+ context
5251
5344
  );
5252
5345
  }
5253
5346
  }
5254
5347
  }
5255
5348
  return 1.2;
5256
5349
  }
5257
- function getDefaultAscenderRatio(paragraphs) {
5350
+ function getDefaultAscenderRatio(paragraphs, context = createLegacyRendererContext()) {
5258
5351
  for (const p of paragraphs) {
5259
5352
  for (const r of p.runs) {
5260
5353
  if (r.properties.fontFamily || r.properties.fontFamilyEa) {
5261
- return getTextMeasurer().getAscenderRatio(
5354
+ return context.textMeasurer.getAscenderRatio(
5262
5355
  r.properties.fontFamily,
5263
- r.properties.fontFamilyEa
5356
+ r.properties.fontFamilyEa,
5357
+ context
5264
5358
  );
5265
5359
  }
5266
5360
  }
5267
5361
  }
5268
5362
  return 1;
5269
5363
  }
5270
- function computeSpAutofitHeight(textBody, transform) {
5364
+ function computeSpAutofitHeight(textBody, transform, context = createLegacyRendererContext()) {
5271
5365
  const { bodyProperties, paragraphs } = textBody;
5272
5366
  const hasText = paragraphs.some((p) => p.runs.some((r) => r.text.length > 0));
5273
5367
  if (!hasText) return null;
@@ -5279,13 +5373,21 @@ function computeSpAutofitHeight(textBody, transform) {
5279
5373
  const textWidth = numCol > 1 ? fullTextWidth / numCol : fullTextWidth;
5280
5374
  const defaultFontSize = getDefaultFontSize(paragraphs);
5281
5375
  const shouldWrap = bodyProperties.wrap !== "none";
5282
- const textHeight = estimateTextHeight(paragraphs, defaultFontSize, shouldWrap, textWidth);
5376
+ const textHeight = estimateTextHeight(
5377
+ paragraphs,
5378
+ defaultFontSize,
5379
+ shouldWrap,
5380
+ textWidth,
5381
+ void 0,
5382
+ void 0,
5383
+ context
5384
+ );
5283
5385
  const requiredHeightPx = textHeight + marginTopPx + marginBottomPx;
5284
5386
  if (requiredHeightPx <= height) return null;
5285
5387
  const DEFAULT_DPI2 = 96;
5286
5388
  return asEmu(requiredHeightPx / DEFAULT_DPI2 * EMU_PER_INCH);
5287
5389
  }
5288
- function computeShrinkToFitScale(paragraphs, defaultFontSize, fontScale, lnSpcReduction, textWidth, availableHeight) {
5390
+ function computeShrinkToFitScale(paragraphs, defaultFontSize, fontScale, lnSpcReduction, textWidth, availableHeight, context = createLegacyRendererContext()) {
5289
5391
  if (availableHeight <= 0) return fontScale;
5290
5392
  const minScale = fontScale * 0.1;
5291
5393
  let scale = fontScale;
@@ -5297,7 +5399,8 @@ function computeShrinkToFitScale(paragraphs, defaultFontSize, fontScale, lnSpcRe
5297
5399
  true,
5298
5400
  textWidth,
5299
5401
  lnSpcReduction,
5300
- scale
5402
+ scale,
5403
+ context
5301
5404
  );
5302
5405
  if (textHeight <= availableHeight) break;
5303
5406
  const newScale = scale * (availableHeight / textHeight);
@@ -5306,15 +5409,15 @@ function computeShrinkToFitScale(paragraphs, defaultFontSize, fontScale, lnSpcRe
5306
5409
  }
5307
5410
  return scale;
5308
5411
  }
5309
- function estimateTextHeight(paragraphs, defaultFontSize, shouldWrap, textWidth, lnSpcReduction = 0, fontScale = 1) {
5412
+ function estimateTextHeight(paragraphs, defaultFontSize, shouldWrap, textWidth, lnSpcReduction = 0, fontScale = 1, context = createLegacyRendererContext()) {
5310
5413
  let totalHeight = 0;
5311
- const defaultRatio = getDefaultLineHeightRatio(paragraphs);
5414
+ const defaultRatio = getDefaultLineHeightRatio(paragraphs, context);
5312
5415
  let prevSpaceAfterPx = 0;
5313
5416
  const scaledDefaultForWrap = defaultFontSize * fontScale;
5314
5417
  for (let pIdx = 0; pIdx < paragraphs.length; pIdx++) {
5315
5418
  const para = paragraphs[pIdx];
5316
5419
  const isEmpty = !para.runs.some((r) => r.text.length > 0);
5317
- const naturalHeightPt = isEmpty && para.endParaRunProperties?.fontSize ? para.endParaRunProperties.fontSize * fontScale * defaultRatio : computeLineNaturalHeight(para.runs, defaultFontSize, fontScale);
5420
+ const naturalHeightPt = isEmpty && para.endParaRunProperties?.fontSize ? para.endParaRunProperties.fontSize * fontScale * defaultRatio : computeLineNaturalHeight(para.runs, defaultFontSize, fontScale, context);
5318
5421
  const lineHeight = getLineHeightPx(
5319
5422
  para,
5320
5423
  naturalHeightPt > 0 ? naturalHeightPt : defaultFontSize * fontScale * defaultRatio,
@@ -5322,7 +5425,14 @@ function estimateTextHeight(paragraphs, defaultFontSize, shouldWrap, textWidth,
5322
5425
  );
5323
5426
  let lineCount;
5324
5427
  if (shouldWrap && para.runs.length > 0 && para.runs.some((r) => r.text.length > 0)) {
5325
- const wrappedLines = wrapParagraph(para, textWidth, scaledDefaultForWrap, fontScale);
5428
+ const wrappedLines = wrapParagraph(
5429
+ para,
5430
+ textWidth,
5431
+ scaledDefaultForWrap,
5432
+ fontScale,
5433
+ context.textMeasurer,
5434
+ context
5435
+ );
5326
5436
  lineCount = wrappedLines.length;
5327
5437
  } else {
5328
5438
  lineCount = para.runs.some((r) => r.text.length > 0) ? 1 : 1;
@@ -5343,9 +5453,9 @@ function computePathLineX(alignment, textStartX, effectiveTextWidth, width, marg
5343
5453
  if (alignment === "r") return width - marginRightPx - lineWidth;
5344
5454
  return textStartX;
5345
5455
  }
5346
- function measureLineWidth(segments, defaultFontSize, fontScale, fontResolver) {
5456
+ function measureLineWidth(segments, defaultFontSize, fontScale, fontResolver, context = createLegacyRendererContext()) {
5347
5457
  let totalWidth = 0;
5348
- const jpanFallback = fontResolver ? getJpanFallbackFont() : null;
5458
+ const jpanFallback = fontResolver ? getJpanFallbackFontFromContext(context) : null;
5349
5459
  for (const seg of segments) {
5350
5460
  const fontSize = (seg.properties.fontSize ?? defaultFontSize) * fontScale;
5351
5461
  if (fontResolver) {
@@ -5353,19 +5463,21 @@ function measureLineWidth(segments, defaultFontSize, fontScale, fontResolver) {
5353
5463
  const font = fontResolver.resolveFont(
5354
5464
  seg.properties.fontFamily,
5355
5465
  seg.properties.fontFamilyEa,
5356
- jpanFallback
5466
+ jpanFallback,
5467
+ context
5357
5468
  );
5358
5469
  if (font) {
5359
5470
  totalWidth += font.getAdvanceWidth(seg.text, fontSizePx);
5360
5471
  continue;
5361
5472
  }
5362
5473
  }
5363
- totalWidth += getTextMeasurer().measureTextWidth(
5474
+ totalWidth += context.textMeasurer.measureTextWidth(
5364
5475
  seg.text,
5365
5476
  fontSize,
5366
5477
  seg.properties.bold,
5367
5478
  seg.properties.fontFamily,
5368
- seg.properties.fontFamilyEa
5479
+ seg.properties.fontFamilyEa,
5480
+ context
5369
5481
  );
5370
5482
  }
5371
5483
  return totalWidth;
@@ -5401,7 +5513,7 @@ function renderTextDecorations(x, y, segmentWidth, fontSizePx, props) {
5401
5513
  }
5402
5514
  return lines;
5403
5515
  }
5404
- function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, fontResolver, vert) {
5516
+ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, fontResolver, context, vert) {
5405
5517
  const fontSize = (props.fontSize ?? defaultFontSize) * fontScale;
5406
5518
  const fontSizePx = fontSize * PX_PER_PT3;
5407
5519
  const parts = [];
@@ -5411,16 +5523,17 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
5411
5523
  if (props.baseline > 0) yOffset = -fontSizePx * 0.35;
5412
5524
  else if (props.baseline < 0) yOffset = fontSizePx * 0.2;
5413
5525
  const effectiveY = y + yOffset;
5414
- const jpanFallback = getJpanFallbackFont();
5526
+ const jpanFallback = getJpanFallbackFontFromContext(context);
5415
5527
  const processSegment = (segText, fontFamily, fontFamilyEa) => {
5416
5528
  if (segText.length === 0) return;
5417
- const font = fontResolver.resolveFont(fontFamily, fontFamilyEa, jpanFallback);
5418
- const segWidth = font ? font.getAdvanceWidth(segText, fontSizePx) : getTextMeasurer().measureTextWidth(
5529
+ const font = fontResolver.resolveFont(fontFamily, fontFamilyEa, jpanFallback, context);
5530
+ const segWidth = font ? font.getAdvanceWidth(segText, fontSizePx) : context.textMeasurer.measureTextWidth(
5419
5531
  segText,
5420
5532
  fontSize,
5421
5533
  props.bold,
5422
5534
  props.fontFamily,
5423
- props.fontFamilyEa
5535
+ props.fontFamilyEa,
5536
+ context
5424
5537
  );
5425
5538
  if (font) {
5426
5539
  const path = font.getPath(segText, x + totalWidth, effectiveY, fontSizePx);
@@ -5437,15 +5550,16 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
5437
5550
  };
5438
5551
  const processCjkUpright = (segText, fontFamily, fontFamilyEa) => {
5439
5552
  if (segText.length === 0) return;
5440
- const font = fontResolver.resolveFont(fontFamily, fontFamilyEa, jpanFallback);
5553
+ const font = fontResolver.resolveFont(fontFamily, fontFamilyEa, jpanFallback, context);
5441
5554
  const fillAttrs = buildPathFillAttrs(props);
5442
5555
  for (const char of segText) {
5443
- const charWidth = font ? font.getAdvanceWidth(char, fontSizePx) : getTextMeasurer().measureTextWidth(
5556
+ const charWidth = font ? font.getAdvanceWidth(char, fontSizePx) : context.textMeasurer.measureTextWidth(
5444
5557
  char,
5445
5558
  fontSize,
5446
5559
  props.bold,
5447
5560
  props.fontFamily,
5448
- props.fontFamilyEa
5561
+ props.fontFamilyEa,
5562
+ context
5449
5563
  );
5450
5564
  if (font) {
5451
5565
  const charX = x + totalWidth;
@@ -5495,13 +5609,13 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
5495
5609
  }
5496
5610
  return { svg, width: totalWidth };
5497
5611
  }
5498
- function renderBulletAsPath(bulletText, x, y, paraProps, textFontSizePt, fontScale, fontResolver, runFontFamily, runFontFamilyEa) {
5612
+ function renderBulletAsPath(bulletText, x, y, paraProps, textFontSizePt, fontScale, fontResolver, context, runFontFamily, runFontFamilyEa) {
5499
5613
  let bulletFontSize = textFontSizePt;
5500
5614
  if (paraProps.bulletSizePct !== null) {
5501
5615
  bulletFontSize = textFontSizePt * (paraProps.bulletSizePct / 1e5);
5502
5616
  }
5503
5617
  const fontSizePx = bulletFontSize * PX_PER_PT3;
5504
- const font = paraProps.bulletFont ? fontResolver.resolveFont(paraProps.bulletFont, null) : fontResolver.resolveFont(runFontFamily ?? null, runFontFamilyEa ?? null);
5618
+ const font = paraProps.bulletFont ? fontResolver.resolveFont(paraProps.bulletFont, null, void 0, context) : fontResolver.resolveFont(runFontFamily ?? null, runFontFamilyEa ?? null, void 0, context);
5505
5619
  if (!font) return [];
5506
5620
  const path = font.getPath(bulletText, x, y, fontSizePx);
5507
5621
  const pathData = path.toPathData(2);
@@ -5517,7 +5631,7 @@ function renderBulletAsPath(bulletText, x, y, paraProps, textFontSizePt, fontSca
5517
5631
  }
5518
5632
  return [`<path d="${pathData}" ${attrs.join(" ")}/>`];
5519
5633
  }
5520
- function renderTextBodyAsPath(textBody, transform, fontResolver) {
5634
+ function renderTextBodyAsPath(textBody, transform, fontResolver, context) {
5521
5635
  const { bodyProperties, paragraphs } = textBody;
5522
5636
  const originalWidth = emuToPixels(transform.extentWidth);
5523
5637
  const originalHeight = emuToPixels(transform.extentHeight);
@@ -5539,12 +5653,13 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5539
5653
  fontScale,
5540
5654
  lnSpcReduction,
5541
5655
  textWidth,
5542
- availableHeight
5656
+ availableHeight,
5657
+ context
5543
5658
  );
5544
5659
  }
5545
5660
  const scaledDefaultFontSizePt = defaultFontSize * fontScale;
5546
- const defaultLineHeightRatio = getDefaultLineHeightRatio(paragraphs);
5547
- const defaultAscenderRatio = getDefaultAscenderRatio(paragraphs);
5661
+ const defaultLineHeightRatio = getDefaultLineHeightRatio(paragraphs, context);
5662
+ const defaultAscenderRatio = getDefaultAscenderRatio(paragraphs, context);
5548
5663
  const defaultNaturalHeightPt = scaledDefaultFontSizePt * defaultLineHeightRatio;
5549
5664
  let yStart = marginTopPx;
5550
5665
  const totalTextHeight = estimateTextHeight(
@@ -5553,7 +5668,8 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5553
5668
  shouldWrap,
5554
5669
  textWidth,
5555
5670
  lnSpcReduction,
5556
- fontScale
5671
+ fontScale,
5672
+ context
5557
5673
  );
5558
5674
  if (bodyProperties.anchor === "ctr") {
5559
5675
  yStart = Math.max(marginTopPx, (height - totalTextHeight) / 2);
@@ -5592,7 +5708,9 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5592
5708
  para,
5593
5709
  effectiveTextWidth,
5594
5710
  scaledDefaultFontSizePt,
5595
- fontScale
5711
+ fontScale,
5712
+ context.textMeasurer,
5713
+ context
5596
5714
  );
5597
5715
  for (let lineIdx = 0; lineIdx < wrappedLines.length; lineIdx++) {
5598
5716
  const line = wrappedLines[lineIdx];
@@ -5607,12 +5725,19 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5607
5725
  const lineNaturalHeightPt = computeLineNaturalHeight(
5608
5726
  line.segments,
5609
5727
  defaultFontSize,
5610
- fontScale
5728
+ fontScale,
5729
+ context
5611
5730
  );
5612
5731
  if (!isFirstLine) {
5613
5732
  currentY += getLineHeightPx(para, lineNaturalHeightPt, lnSpcReduction) + lineGapPx;
5614
5733
  }
5615
- const lineWidth = measureLineWidth(line.segments, defaultFontSize, fontScale, fontResolver);
5734
+ const lineWidth = measureLineWidth(
5735
+ line.segments,
5736
+ defaultFontSize,
5737
+ fontScale,
5738
+ fontResolver,
5739
+ context
5740
+ );
5616
5741
  const lineStartX = computePathLineX(
5617
5742
  para.properties.alignment,
5618
5743
  textStartX,
@@ -5634,6 +5759,7 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5634
5759
  lineFontSize,
5635
5760
  fontScale,
5636
5761
  fontResolver,
5762
+ context,
5637
5763
  firstSeg?.properties.fontFamily,
5638
5764
  firstSeg?.properties.fontFamilyEa
5639
5765
  )
@@ -5648,6 +5774,7 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5648
5774
  fontScale,
5649
5775
  defaultFontSize,
5650
5776
  fontResolver,
5777
+ context,
5651
5778
  bodyProperties.vert
5652
5779
  );
5653
5780
  if (result.svg) elements.push(result.svg);
@@ -5656,12 +5783,23 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5656
5783
  isFirstLine = false;
5657
5784
  }
5658
5785
  } else {
5659
- const naturalHeightPt = computeLineNaturalHeight(para.runs, defaultFontSize, fontScale);
5786
+ const naturalHeightPt = computeLineNaturalHeight(
5787
+ para.runs,
5788
+ defaultFontSize,
5789
+ fontScale,
5790
+ context
5791
+ );
5660
5792
  if (!isFirstLine) {
5661
5793
  currentY += getLineHeightPx(para, naturalHeightPt, lnSpcReduction) + paragraphGapPx;
5662
5794
  }
5663
5795
  const runsAsSegments = para.runs.filter((r) => r.text.length > 0).map((r) => ({ text: r.text, properties: r.properties }));
5664
- const lineWidth = measureLineWidth(runsAsSegments, defaultFontSize, fontScale, fontResolver);
5796
+ const lineWidth = measureLineWidth(
5797
+ runsAsSegments,
5798
+ defaultFontSize,
5799
+ fontScale,
5800
+ fontResolver,
5801
+ context
5802
+ );
5665
5803
  const lineStartX = computePathLineX(
5666
5804
  para.properties.alignment,
5667
5805
  textStartX,
@@ -5683,6 +5821,7 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5683
5821
  fontSize,
5684
5822
  fontScale,
5685
5823
  fontResolver,
5824
+ context,
5686
5825
  firstRun?.properties.fontFamily,
5687
5826
  firstRun?.properties.fontFamilyEa
5688
5827
  )
@@ -5698,6 +5837,7 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
5698
5837
  fontScale,
5699
5838
  defaultFontSize,
5700
5839
  fontResolver,
5840
+ context,
5701
5841
  bodyProperties.vert
5702
5842
  );
5703
5843
  if (result.svg) elements.push(result.svg);
@@ -5723,11 +5863,11 @@ function escapeXml2(str) {
5723
5863
  }
5724
5864
 
5725
5865
  // ../renderer/src/renderer/shape-renderer.ts
5726
- function renderShape(shape) {
5866
+ function renderShape(shape, context = createLegacyRendererContext()) {
5727
5867
  const { transform, geometry, fill, outline, textBody, effects } = shape;
5728
5868
  let effectiveTransform = transform;
5729
5869
  if (textBody?.bodyProperties.autoFit === "spAutofit") {
5730
- const requiredHeightEmu = computeSpAutofitHeight(textBody, transform);
5870
+ const requiredHeightEmu = computeSpAutofitHeight(textBody, transform, context);
5731
5871
  if (requiredHeightEmu !== null) {
5732
5872
  effectiveTransform = { ...transform, extentHeight: requiredHeightEmu };
5733
5873
  }
@@ -5754,7 +5894,7 @@ function renderShape(shape) {
5754
5894
  parts.push(styledGeometry);
5755
5895
  }
5756
5896
  if (textBody) {
5757
- const textSvg = renderTextBody(textBody, effectiveTransform);
5897
+ const textSvg = renderTextBody(textBody, effectiveTransform, context);
5758
5898
  if (textSvg) {
5759
5899
  parts.push(textSvg);
5760
5900
  }
@@ -5794,7 +5934,7 @@ function renderConnector(connector) {
5794
5934
  }
5795
5935
 
5796
5936
  // ../renderer/src/renderer/table-renderer.ts
5797
- function renderTable(element) {
5937
+ function renderTable(element, context = createLegacyRendererContext()) {
5798
5938
  const { transform, table } = element;
5799
5939
  const transformAttr = buildTransformAttr(transform);
5800
5940
  const colWidths = table.columns.map((col) => emuToPixels(col.width));
@@ -5857,7 +5997,7 @@ function renderTable(element) {
5857
5997
  flipH: false,
5858
5998
  flipV: false
5859
5999
  };
5860
- const textSvg = renderTextBody(cell.textBody, cellTransform);
6000
+ const textSvg = renderTextBody(cell.textBody, cellTransform, context);
5861
6001
  if (textSvg) {
5862
6002
  parts.push(`<g transform="translate(${x}, ${y})">${textSvg}</g>`);
5863
6003
  }
@@ -5882,7 +6022,7 @@ function pixelsToEmu(px) {
5882
6022
  }
5883
6023
 
5884
6024
  // ../renderer/src/renderer/svg-renderer.ts
5885
- function renderSlideToSvg(slide, slideSize) {
6025
+ function renderSlideToSvg(slide, slideSize, context = createLegacyRendererContext()) {
5886
6026
  const width = emuToPixels(slideSize.width);
5887
6027
  const height = emuToPixels(slideSize.height);
5888
6028
  const parts = [];
@@ -5903,7 +6043,7 @@ function renderSlideToSvg(slide, slideSize) {
5903
6043
  parts.push(`<rect width="${width}" height="${height}" fill="#FFFFFF"/>`);
5904
6044
  }
5905
6045
  for (const element of slide.elements) {
5906
- const result = renderElement(element);
6046
+ const result = renderElement(element, context);
5907
6047
  if (result) {
5908
6048
  parts.push(result.content);
5909
6049
  defs.push(...result.defs);
@@ -5915,11 +6055,11 @@ function renderSlideToSvg(slide, slideSize) {
5915
6055
  parts.push("</svg>");
5916
6056
  return parts.join("");
5917
6057
  }
5918
- function renderElement(element) {
6058
+ function renderElement(element, context) {
5919
6059
  let result = null;
5920
6060
  switch (element.type) {
5921
6061
  case "shape":
5922
- result = renderShape(element);
6062
+ result = renderShape(element, context);
5923
6063
  break;
5924
6064
  case "image":
5925
6065
  result = renderImage(element);
@@ -5928,13 +6068,13 @@ function renderElement(element) {
5928
6068
  result = renderConnector(element);
5929
6069
  break;
5930
6070
  case "group":
5931
- result = renderGroup(element);
6071
+ result = renderGroup(element, context);
5932
6072
  break;
5933
6073
  case "chart":
5934
- result = renderChart(element);
6074
+ result = renderChart(element, context);
5935
6075
  break;
5936
6076
  case "table":
5937
- result = renderTable(element);
6077
+ result = renderTable(element, context);
5938
6078
  break;
5939
6079
  }
5940
6080
  if (result && "altText" in element && element.altText) {
@@ -5950,7 +6090,7 @@ function addAriaLabel(svgFragment, altText) {
5950
6090
  const escaped = altText.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
5951
6091
  return svgFragment.replace(/^<(g|image|path)\b/, `<$1 role="img" aria-label="${escaped}"`);
5952
6092
  }
5953
- function renderGroup(group) {
6093
+ function renderGroup(group, context) {
5954
6094
  const x = emuToPixels(group.transform.offsetX);
5955
6095
  const y = emuToPixels(group.transform.offsetY);
5956
6096
  const w = emuToPixels(group.transform.extentWidth);
@@ -5980,7 +6120,7 @@ function renderGroup(group) {
5980
6120
  const defs = [];
5981
6121
  parts.push(`<g transform="${transformParts.join(" ")}">`);
5982
6122
  for (const child of group.children) {
5983
- const childResult = renderElement(child);
6123
+ const childResult = renderElement(child, context);
5984
6124
  if (childResult) {
5985
6125
  parts.push(childResult.content);
5986
6126
  defs.push(...childResult.defs);
@@ -6020,6 +6160,58 @@ function asSourceNodeId(value) {
6020
6160
  function asRawSidecarId(value) {
6021
6161
  return unsafeBrandAssertion2(value);
6022
6162
  }
6163
+ var RELS_SUFFIX = ".rels";
6164
+ var RELS_MARKER = "_rels/";
6165
+ var ABSOLUTE_URI_PATTERN = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
6166
+ function isRelationshipPart(path) {
6167
+ return path.endsWith(RELS_SUFFIX) && path.includes(RELS_MARKER);
6168
+ }
6169
+ function relationshipsSourcePartPath(relsPath) {
6170
+ const idx = relsPath.lastIndexOf(RELS_MARKER);
6171
+ const dir = relsPath.slice(0, idx);
6172
+ const file = relsPath.slice(idx + RELS_MARKER.length);
6173
+ const base = file.endsWith(RELS_SUFFIX) ? file.slice(0, -RELS_SUFFIX.length) : file;
6174
+ return asPartPath(dir + base);
6175
+ }
6176
+ function resolveRelationshipTarget(sourcePartPath, target) {
6177
+ if (ABSOLUTE_URI_PATTERN.test(target)) return target;
6178
+ const combined = target.startsWith("/") ? target.slice(1) : joinPackageRelativeTarget(sourcePartPath, target);
6179
+ return normalizePackagePath(combined);
6180
+ }
6181
+ function resolveInternalRelationshipTarget(sourcePartPath, relationship) {
6182
+ if (relationship.targetMode === "External") return void 0;
6183
+ return asPartPath(resolveRelationshipTarget(sourcePartPath, relationship.target));
6184
+ }
6185
+ function parseRelationshipTargetMode(value) {
6186
+ if (value === "Internal" || value === "External") return value;
6187
+ return void 0;
6188
+ }
6189
+ function joinPackageRelativeTarget(sourcePartPath, target) {
6190
+ const slash = sourcePartPath.lastIndexOf("/");
6191
+ const baseDir = slash === -1 ? "" : sourcePartPath.slice(0, slash);
6192
+ return baseDir === "" ? target : `${baseDir}/${target}`;
6193
+ }
6194
+ function normalizePackagePath(path) {
6195
+ const segments = [];
6196
+ for (const segment of path.split("/")) {
6197
+ if (segment === "" || segment === ".") continue;
6198
+ if (segment === "..") {
6199
+ segments.pop();
6200
+ continue;
6201
+ }
6202
+ segments.push(segment);
6203
+ }
6204
+ return segments.join("/");
6205
+ }
6206
+ var EDITABLE_TEXT_RUN_PROPERTIES = [
6207
+ "bold",
6208
+ "italic",
6209
+ "underline",
6210
+ "fontSize",
6211
+ "color",
6212
+ "typeface"
6213
+ ];
6214
+ var EDITABLE_TEXT_RUN_PROPERTY_SET = new Set(EDITABLE_TEXT_RUN_PROPERTIES);
6023
6215
  function asEmu2(value) {
6024
6216
  return unsafeBrandAssertion2(value);
6025
6217
  }
@@ -6629,14 +6821,14 @@ function parseLineJoin(ln) {
6629
6821
  }
6630
6822
  function parseArrowEndpoint(node) {
6631
6823
  if (!node) return void 0;
6632
- const type = parseEnumValue(getAttr(node, "type"), ARROW_TYPES);
6824
+ const type = parseEnumValue(getAttr(node, "type"), ARROW_TYPES2);
6633
6825
  if (type === void 0) return void 0;
6634
6826
  const width = getAttr(node, "w") ?? "med";
6635
6827
  const length = getAttr(node, "len") ?? "med";
6636
6828
  return {
6637
6829
  type,
6638
- width: parseEnumValueWithDefault(width, ARROW_SIZES, "med"),
6639
- length: parseEnumValueWithDefault(length, ARROW_SIZES, "med")
6830
+ width: parseEnumValueWithDefault(width, ARROW_SIZES2, "med"),
6831
+ length: parseEnumValueWithDefault(length, ARROW_SIZES2, "med")
6640
6832
  };
6641
6833
  }
6642
6834
  var DASH_STYLES = /* @__PURE__ */ new Set([
@@ -6649,14 +6841,14 @@ var DASH_STYLES = /* @__PURE__ */ new Set([
6649
6841
  "sysDash",
6650
6842
  "sysDot"
6651
6843
  ]);
6652
- var ARROW_TYPES = /* @__PURE__ */ new Set([
6844
+ var ARROW_TYPES2 = /* @__PURE__ */ new Set([
6653
6845
  "triangle",
6654
6846
  "stealth",
6655
6847
  "diamond",
6656
6848
  "oval",
6657
6849
  "arrow"
6658
6850
  ]);
6659
- var ARROW_SIZES = /* @__PURE__ */ new Set(["sm", "med", "lg"]);
6851
+ var ARROW_SIZES2 = /* @__PURE__ */ new Set(["sm", "med", "lg"]);
6660
6852
  function parseCustomGeometry(custGeom, orderedCustGeom) {
6661
6853
  const pathLst = getChild(custGeom, "pathLst");
6662
6854
  const paths = getChildArray(pathLst, "path");
@@ -7595,8 +7787,10 @@ function parseShape(sp, partPath, nextId, orderingSlot, orderedNode) {
7595
7787
  function parseConnector(cxnSp, partPath, nextId, orderingSlot, orderedNode) {
7596
7788
  const nvCxnSpPr = getChild(cxnSp, "nvCxnSpPr");
7597
7789
  const cNvPr = getChild(nvCxnSpPr, "cNvPr");
7790
+ const cNvCxnSpPr = getChild(nvCxnSpPr, "cNvCxnSpPr");
7598
7791
  const nodeId = sourceNodeId(cNvPr);
7599
7792
  const name = getAttr(cNvPr, "name");
7793
+ const connection = parseConnectorConnection(cNvCxnSpPr);
7600
7794
  const spPr = getChild(cxnSp, "spPr");
7601
7795
  const transform = parseTransform(spPr);
7602
7796
  const geometry = parseGeometry(spPr, orderedNestedChildChildren(orderedNode, "cxnSp", "spPr"));
@@ -7612,6 +7806,7 @@ function parseConnector(cxnSp, partPath, nextId, orderingSlot, orderedNode) {
7612
7806
  kind: "connector",
7613
7807
  ...nodeId !== void 0 ? { nodeId } : {},
7614
7808
  ...name !== void 0 ? { name } : {},
7809
+ ...connection !== void 0 ? { connection } : {},
7615
7810
  ...transform !== void 0 ? { transform } : {},
7616
7811
  ...geometry !== void 0 ? { geometry } : {},
7617
7812
  ...outline !== void 0 ? { outline } : {},
@@ -7621,6 +7816,23 @@ function parseConnector(cxnSp, partPath, nextId, orderingSlot, orderedNode) {
7621
7816
  ...rawSidecars.length > 0 ? { rawSidecars } : {}
7622
7817
  };
7623
7818
  }
7819
+ function parseConnectorConnection(cNvCxnSpPr) {
7820
+ const start = parseConnectorConnectionEndpoint(getChild(cNvCxnSpPr, "stCxn"));
7821
+ const end = parseConnectorConnectionEndpoint(getChild(cNvCxnSpPr, "endCxn"));
7822
+ return start !== void 0 || end !== void 0 ? {
7823
+ ...start !== void 0 ? { start } : {},
7824
+ ...end !== void 0 ? { end } : {}
7825
+ } : void 0;
7826
+ }
7827
+ function parseConnectorConnectionEndpoint(node) {
7828
+ const shapeId = getAttr(node, "id");
7829
+ const connectionSiteIndex = numericAttr(node, "idx");
7830
+ if (shapeId === void 0 || connectionSiteIndex === void 0) return void 0;
7831
+ return {
7832
+ shapeId: asSourceNodeId(shapeId),
7833
+ connectionSiteIndex
7834
+ };
7835
+ }
7624
7836
  function parseShapeStyle(style) {
7625
7837
  if (style === void 0) return void 0;
7626
7838
  const fillRef = parseStyleReference(getChild(style, "fillRef"));
@@ -8501,49 +8713,6 @@ function getPlaceholderFallbackType(type) {
8501
8713
  if (type === "subTitle") return "body";
8502
8714
  return void 0;
8503
8715
  }
8504
- var RELS_SUFFIX = ".rels";
8505
- var RELS_MARKER = "_rels/";
8506
- var ABSOLUTE_URI_PATTERN = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
8507
- function isRelationshipPart(path) {
8508
- return path.endsWith(RELS_SUFFIX) && path.includes(RELS_MARKER);
8509
- }
8510
- function relationshipsSourcePartPath(relsPath) {
8511
- const idx = relsPath.lastIndexOf(RELS_MARKER);
8512
- const dir = relsPath.slice(0, idx);
8513
- const file = relsPath.slice(idx + RELS_MARKER.length);
8514
- const base = file.endsWith(RELS_SUFFIX) ? file.slice(0, -RELS_SUFFIX.length) : file;
8515
- return asPartPath(dir + base);
8516
- }
8517
- function resolveRelationshipTarget(sourcePartPath, target) {
8518
- if (ABSOLUTE_URI_PATTERN.test(target)) return target;
8519
- const combined = target.startsWith("/") ? target.slice(1) : joinPackageRelativeTarget(sourcePartPath, target);
8520
- return normalizePackagePath(combined);
8521
- }
8522
- function resolveInternalRelationshipTarget(sourcePartPath, relationship) {
8523
- if (relationship.targetMode === "External") return void 0;
8524
- return asPartPath(resolveRelationshipTarget(sourcePartPath, relationship.target));
8525
- }
8526
- function parseRelationshipTargetMode(value) {
8527
- if (value === "Internal" || value === "External") return value;
8528
- return void 0;
8529
- }
8530
- function joinPackageRelativeTarget(sourcePartPath, target) {
8531
- const slash = sourcePartPath.lastIndexOf("/");
8532
- const baseDir = slash === -1 ? "" : sourcePartPath.slice(0, slash);
8533
- return baseDir === "" ? target : `${baseDir}/${target}`;
8534
- }
8535
- function normalizePackagePath(path) {
8536
- const segments = [];
8537
- for (const segment of path.split("/")) {
8538
- if (segment === "" || segment === ".") continue;
8539
- if (segment === "..") {
8540
- segments.pop();
8541
- continue;
8542
- }
8543
- segments.push(segment);
8544
- }
8545
- return segments.join("/");
8546
- }
8547
8716
  function resolveComputedRelationships(source, sourcePartPath) {
8548
8717
  const rels = source.packageGraph.relationships.find((entry) => entry.sourcePartPath === sourcePartPath)?.relationships ?? [];
8549
8718
  return rels.map((relationship) => {
@@ -8565,7 +8734,7 @@ function resolveComputedRelationships(source, sourcePartPath) {
8565
8734
  function findMedia(media, partPath) {
8566
8735
  return media.find((part) => part.partPath === partPath);
8567
8736
  }
8568
- var IMAGE_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
8737
+ var IMAGE_REL_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
8569
8738
  var CHART_REL_TYPES = /* @__PURE__ */ new Set([
8570
8739
  "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
8571
8740
  "http://purl.oclc.org/ooxml/officeDocument/relationships/chart"
@@ -8782,7 +8951,7 @@ function computeShapeElement(context, shape, layer, partPath) {
8782
8951
  }
8783
8952
  function computeImageElement(context, image, layer, partPath) {
8784
8953
  const relationship = resolveComputedRelationships(context.source, partPath).find(
8785
- (rel) => rel.id === image.blipRelationshipId && rel.type === IMAGE_REL_TYPE
8954
+ (rel) => rel.id === image.blipRelationshipId && rel.type === IMAGE_REL_TYPE2
8786
8955
  );
8787
8956
  const effects = image.effects !== void 0 ? computeEffectList(context, image.effects) : void 0;
8788
8957
  const blipEffects = image.blipEffects !== void 0 ? computeBlipEffects(context, image.blipEffects) : void 0;
@@ -8980,7 +9149,7 @@ function computeFill(context, fill, partPath) {
8980
9149
  };
8981
9150
  case "image": {
8982
9151
  const relationship = resolveComputedRelationships(context.source, partPath).find(
8983
- (rel) => rel.id === fill.blipRelationshipId && rel.type === IMAGE_REL_TYPE
9152
+ (rel) => rel.id === fill.blipRelationshipId && rel.type === IMAGE_REL_TYPE2
8984
9153
  );
8985
9154
  return {
8986
9155
  kind: "image",
@@ -9346,6 +9515,7 @@ function parseSlide(root, partPath, layoutPartPath, nextId, orderedSpTree) {
9346
9515
  function parseSlideLayout(root, partPath, masterPartPath, nextId, orderedSpTree) {
9347
9516
  const cSld = getChild(root, "cSld");
9348
9517
  const type = getAttr(root, "type");
9518
+ const show = booleanAttr(root, "show");
9349
9519
  const background = parseBackground(getChild(cSld, "bg"), nextId);
9350
9520
  const colorMapOverride = parseColorMapOverride(getChild(root, "clrMapOvr"));
9351
9521
  const showMasterShapes = booleanAttr(root, "showMasterSp");
@@ -9353,6 +9523,7 @@ function parseSlideLayout(root, partPath, masterPartPath, nextId, orderedSpTree)
9353
9523
  partPath,
9354
9524
  masterPartPath,
9355
9525
  ...type !== void 0 ? { type } : {},
9526
+ ...show !== void 0 ? { show } : {},
9356
9527
  ...background !== void 0 ? { background } : {},
9357
9528
  ...colorMapOverride !== void 0 ? { colorMapOverride } : {},
9358
9529
  ...showMasterShapes !== void 0 ? { showMasterShapes } : {},
@@ -9587,21 +9758,21 @@ function isNonEmpty(value) {
9587
9758
  var CONTENT_TYPES_PART = "[Content_Types].xml";
9588
9759
  var PACKAGE_ROOT_PART = "";
9589
9760
  var OFFICE_DOCUMENT_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
9590
- var SLIDE_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide";
9591
- var SLIDE_LAYOUT_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout";
9761
+ var SLIDE_REL_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide";
9762
+ var SLIDE_LAYOUT_REL_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout";
9592
9763
  var SLIDE_MASTER_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster";
9593
9764
  var THEME_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
9594
9765
  var PRESENTATION_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml";
9595
9766
  var textDecoder2 = new TextDecoder();
9596
9767
  function readPptx(input) {
9597
- const entries2 = unzipPackage(input);
9768
+ const entries = unzipPackage(input);
9598
9769
  const diagnostics = [];
9599
- const contentTypes = readContentTypes(entries2);
9600
- const relationships = readRelationships(entries2);
9770
+ const contentTypes = readContentTypes(entries);
9771
+ const relationships = readRelationships(entries);
9601
9772
  const parts = [];
9602
9773
  const media = [];
9603
9774
  const rawParts = [];
9604
- for (const [path, bytes] of entries2) {
9775
+ for (const [path, bytes] of entries) {
9605
9776
  if (path === CONTENT_TYPES_PART) continue;
9606
9777
  const contentType = resolveContentType(path, contentTypes.defaults, contentTypes.overrides);
9607
9778
  parts.push({ partPath: asPartPath(path), contentType });
@@ -9613,12 +9784,12 @@ function readPptx(input) {
9613
9784
  rawParts.push({ kind: "binary", partPath: asPartPath(path), contentType, bytes });
9614
9785
  }
9615
9786
  const presentation = readPresentation(
9616
- entries2,
9787
+ entries,
9617
9788
  relationships,
9618
9789
  contentTypes.overrides,
9619
9790
  diagnostics
9620
9791
  );
9621
- const hierarchy = readSlideHierarchy(entries2, relationships, presentation, diagnostics);
9792
+ const hierarchy = readSlideHierarchy(entries, relationships, presentation, diagnostics);
9622
9793
  return {
9623
9794
  packageGraph: {
9624
9795
  contentTypes,
@@ -9635,13 +9806,13 @@ function readPptx(input) {
9635
9806
  diagnostics
9636
9807
  };
9637
9808
  }
9638
- function readSlideHierarchy(entries2, relationships, presentation, diagnostics) {
9809
+ function readSlideHierarchy(entries, relationships, presentation, diagnostics) {
9639
9810
  const slides = [];
9640
9811
  const layoutPaths = new OrderedPathSet();
9641
9812
  for (const slidePath of presentation.slidePartPaths) {
9642
- const part = parsePartRoot(entries2, slidePath, "sld", diagnostics, true);
9813
+ const part = parsePartRoot(entries, slidePath, "sld", diagnostics, true);
9643
9814
  if (part === void 0) continue;
9644
- const layoutPath = resolveSingleRel(relationships, slidePath, SLIDE_LAYOUT_REL_TYPE);
9815
+ const layoutPath = resolveSingleRel(relationships, slidePath, SLIDE_LAYOUT_REL_TYPE2);
9645
9816
  if (layoutPath === void 0) {
9646
9817
  diagnostics.push({
9647
9818
  severity: "warning",
@@ -9665,7 +9836,7 @@ function readSlideHierarchy(entries2, relationships, presentation, diagnostics)
9665
9836
  const slideLayouts = [];
9666
9837
  const masterPaths = new OrderedPathSet();
9667
9838
  for (const layoutPath of layoutPaths.values()) {
9668
- const part = parsePartRoot(entries2, layoutPath, "sldLayout", diagnostics, true);
9839
+ const part = parsePartRoot(entries, layoutPath, "sldLayout", diagnostics, true);
9669
9840
  if (part === void 0) continue;
9670
9841
  const masterPath = resolveSingleRel(relationships, layoutPath, SLIDE_MASTER_REL_TYPE);
9671
9842
  if (masterPath !== void 0) masterPaths.add(masterPath);
@@ -9679,14 +9850,21 @@ function readSlideHierarchy(entries2, relationships, presentation, diagnostics)
9679
9850
  )
9680
9851
  );
9681
9852
  }
9853
+ for (const masterPath of resolveAllRels(
9854
+ relationships,
9855
+ presentation.partPath,
9856
+ SLIDE_MASTER_REL_TYPE
9857
+ )) {
9858
+ masterPaths.add(masterPath);
9859
+ }
9682
9860
  const slideMasters = [];
9683
9861
  const themePaths = new OrderedPathSet();
9684
9862
  for (const masterPath of masterPaths.values()) {
9685
- const part = parsePartRoot(entries2, masterPath, "sldMaster", diagnostics, true);
9863
+ const part = parsePartRoot(entries, masterPath, "sldMaster", diagnostics, true);
9686
9864
  if (part === void 0) continue;
9687
9865
  const themePath = resolveSingleRel(relationships, masterPath, THEME_REL_TYPE);
9688
9866
  if (themePath !== void 0) themePaths.add(themePath);
9689
- const masterLayoutPaths = resolveAllRels(relationships, masterPath, SLIDE_LAYOUT_REL_TYPE);
9867
+ const masterLayoutPaths = resolveAllRels(relationships, masterPath, SLIDE_LAYOUT_REL_TYPE2);
9690
9868
  slideMasters.push(
9691
9869
  parseSlideMaster(
9692
9870
  part.root,
@@ -9698,9 +9876,26 @@ function readSlideHierarchy(entries2, relationships, presentation, diagnostics)
9698
9876
  )
9699
9877
  );
9700
9878
  }
9879
+ const readLayoutPaths = new Set(slideLayouts.map((layout) => layout.partPath));
9880
+ for (const layoutPath of slideMasters.flatMap((master) => master.layoutPartPaths)) {
9881
+ if (readLayoutPaths.has(layoutPath)) continue;
9882
+ const part = parsePartRoot(entries, layoutPath, "sldLayout", diagnostics, true);
9883
+ if (part === void 0) continue;
9884
+ const masterPath = resolveSingleRel(relationships, layoutPath, SLIDE_MASTER_REL_TYPE);
9885
+ slideLayouts.push(
9886
+ parseSlideLayout(
9887
+ part.root,
9888
+ layoutPath,
9889
+ masterPath ?? asPartPath(""),
9890
+ createSidecarIdFactory(layoutPath),
9891
+ navigateOrdered(part.orderedRoot, ["cSld", "spTree"])
9892
+ )
9893
+ );
9894
+ readLayoutPaths.add(layoutPath);
9895
+ }
9701
9896
  const themes = [];
9702
9897
  for (const themePath of themePaths.values()) {
9703
- const part = parsePartRoot(entries2, themePath, "theme", diagnostics, true);
9898
+ const part = parsePartRoot(entries, themePath, "theme", diagnostics, true);
9704
9899
  if (part === void 0) continue;
9705
9900
  themes.push(
9706
9901
  parseTheme(part.root, themePath, createSidecarIdFactory(themePath), part.orderedRoot)
@@ -9708,8 +9903,8 @@ function readSlideHierarchy(entries2, relationships, presentation, diagnostics)
9708
9903
  }
9709
9904
  return { slides, slideLayouts, slideMasters, themes };
9710
9905
  }
9711
- function parsePartRoot(entries2, partPath, rootLocalName, diagnostics, includeOrderedRoot) {
9712
- const bytes = entries2.get(partPath);
9906
+ function parsePartRoot(entries, partPath, rootLocalName, diagnostics, includeOrderedRoot) {
9907
+ const bytes = entries.get(partPath);
9713
9908
  if (!bytes) {
9714
9909
  diagnostics.push({
9715
9910
  severity: "warning",
@@ -9760,15 +9955,15 @@ var OrderedPathSet = class {
9760
9955
  };
9761
9956
  function unzipPackage(input) {
9762
9957
  const unzipped = (0, import_fflate.unzipSync)(input);
9763
- const entries2 = /* @__PURE__ */ new Map();
9958
+ const entries = /* @__PURE__ */ new Map();
9764
9959
  for (const [path, bytes] of Object.entries(unzipped)) {
9765
9960
  if (path.endsWith("/")) continue;
9766
- entries2.set(path, bytes);
9961
+ entries.set(path, bytes);
9767
9962
  }
9768
- return entries2;
9963
+ return entries;
9769
9964
  }
9770
- function readContentTypes(entries2) {
9771
- const bytes = entries2.get(CONTENT_TYPES_PART);
9965
+ function readContentTypes(entries) {
9966
+ const bytes = entries.get(CONTENT_TYPES_PART);
9772
9967
  if (!bytes) return { defaults: [], overrides: [] };
9773
9968
  const root = getChild(parseXml(textDecoder2.decode(bytes)), "Types");
9774
9969
  const defaults = [];
@@ -9787,9 +9982,9 @@ function readContentTypes(entries2) {
9787
9982
  }
9788
9983
  return { defaults, overrides };
9789
9984
  }
9790
- function readRelationships(entries2) {
9985
+ function readRelationships(entries) {
9791
9986
  const result = [];
9792
- for (const [path, bytes] of entries2) {
9987
+ for (const [path, bytes] of entries) {
9793
9988
  if (!isRelationshipPart(path)) continue;
9794
9989
  const root = getChild(parseXml(textDecoder2.decode(bytes)), "Relationships");
9795
9990
  const relationships = [];
@@ -9810,12 +10005,12 @@ function readRelationships(entries2) {
9810
10005
  }
9811
10006
  return result;
9812
10007
  }
9813
- function readPresentation(entries2, relationships, overrides, diagnostics) {
10008
+ function readPresentation(entries, relationships, overrides, diagnostics) {
9814
10009
  const presentationPath = locatePresentationPart(relationships, overrides);
9815
10010
  if (presentationPath === void 0) {
9816
10011
  throw new Error("readPptx: presentation part not found; input is not a valid PPTX package");
9817
10012
  }
9818
- const bytes = entries2.get(presentationPath);
10013
+ const bytes = entries.get(presentationPath);
9819
10014
  if (!bytes) {
9820
10015
  throw new Error(
9821
10016
  `readPptx: presentation part '${presentationPath}' is missing from the package`
@@ -9849,7 +10044,7 @@ function readPresentation(entries2, relationships, overrides, diagnostics) {
9849
10044
  });
9850
10045
  continue;
9851
10046
  }
9852
- if (relationship.type !== SLIDE_REL_TYPE || relationship.targetMode === "External") {
10047
+ if (relationship.type !== SLIDE_REL_TYPE2 || relationship.targetMode === "External") {
9853
10048
  diagnostics.push({
9854
10049
  severity: "warning",
9855
10050
  code: "slide-relationship-invalid",
@@ -10572,74 +10767,65 @@ function pushAdapterWarning(diagnostics, code, message, slide, sourcePartPath) {
10572
10767
 
10573
10768
  // src/svg-converter.ts
10574
10769
  async function convertPptxToSvg(input, options, loadSystemFontSetup2) {
10770
+ const source = readPptx(input);
10771
+ return renderPptxSourceModelToSvg(source, options, loadSystemFontSetup2);
10772
+ }
10773
+ async function renderPptxSourceModelToSvg(source, options, loadSystemFontSetup2) {
10575
10774
  const textOutput = options?.textOutput ?? "path";
10576
10775
  const logLevel = options?.logLevel ?? "off";
10577
10776
  const setup = await createOpentypeSetup(options, loadSystemFontSetup2);
10578
- if (setup) {
10579
- setTextMeasurer(setup.measurer);
10580
- if (textOutput !== "text") {
10581
- setTextPathFontResolver(setup.fontResolver);
10582
- }
10583
- }
10584
10777
  const fontUsageCollector = textOutput === "text" ? new FontUsageCollector() : null;
10585
- if (fontUsageCollector) {
10586
- setFontUsageCollector(fontUsageCollector);
10778
+ const scriptFontScheme = findScriptFontScheme(source);
10779
+ const warningLogger = createWarningLogger(logLevel === "off" ? "warn" : logLevel);
10780
+ const context = createRendererContext({
10781
+ ...setup !== null ? { textMeasurer: setup.measurer } : {},
10782
+ textPathFontResolver: setup !== null && textOutput !== "text" ? setup.fontResolver : null,
10783
+ fontUsageCollector,
10784
+ fontMapping: createFontMapping(options?.fontMapping),
10785
+ scriptFonts: {
10786
+ majorJpan: scriptFontScheme?.majorJapanese ?? null,
10787
+ minorJpan: scriptFontScheme?.minorJapanese ?? null
10788
+ },
10789
+ warningLogger
10790
+ });
10791
+ if (source.presentation.slidePartPaths.length === 0) {
10792
+ context.warningLogger.warn("presentation.noSlides", "No slides found in the PPTX file");
10587
10793
  }
10588
- setFontMapping(createFontMapping(options?.fontMapping));
10589
- try {
10590
- initWarningLogger(logLevel === "off" ? "warn" : logLevel);
10591
- const source = readPptx(input);
10592
- const scriptFontScheme = findScriptFontScheme(source);
10593
- setScriptFonts(
10594
- scriptFontScheme?.majorJapanese ?? null,
10595
- scriptFontScheme?.minorJapanese ?? null
10596
- );
10597
- if (source.presentation.slidePartPaths.length === 0) {
10598
- warn("presentation.noSlides", "No slides found in the PPTX file");
10599
- }
10600
- const computed = createComputedView(source, { slides: options?.slides });
10601
- const adapted = adaptComputedViewToRendererModel(computed);
10602
- const slideSize = adapted.slideSize;
10603
- if (slideSize === void 0 && adapted.slides.length > 0) {
10604
- throw new Error("Converter requires a computed slide size");
10605
- }
10606
- const slides = [];
10607
- for (const slide of adapted.slides) {
10608
- if (slideSize === void 0) continue;
10609
- fontUsageCollector?.reset();
10610
- let svg = renderSlideToSvg(slide, slideSize);
10611
- if (fontUsageCollector && setup) {
10612
- const style = await buildFontFaceStyle(fontUsageCollector.getUsages(), setup.fontResolver);
10613
- if (style) {
10614
- svg = injectIntoSvgDefs(svg, style);
10615
- }
10794
+ const computed = createComputedView(source, { slides: options?.slides });
10795
+ const adapted = adaptComputedViewToRendererModel(computed);
10796
+ const slideSize = adapted.slideSize;
10797
+ if (slideSize === void 0 && adapted.slides.length > 0) {
10798
+ throw new Error("Converter requires a computed slide size");
10799
+ }
10800
+ const slides = [];
10801
+ for (const slide of adapted.slides) {
10802
+ if (slideSize === void 0) continue;
10803
+ fontUsageCollector?.reset();
10804
+ let svg = renderSlideToSvg(slide, slideSize, context);
10805
+ if (fontUsageCollector && setup) {
10806
+ const style = await buildFontFaceStyle(
10807
+ fontUsageCollector.getUsages(),
10808
+ setup.fontResolver,
10809
+ context
10810
+ );
10811
+ if (style) {
10812
+ svg = injectIntoSvgDefs(svg, style);
10616
10813
  }
10617
- slides.push({ slideNumber: slide.slideNumber, svg });
10618
10814
  }
10619
- const rendererWarningEntries = [...getWarningEntries()];
10620
- if (logLevel === "off") {
10621
- initWarningLogger("off");
10622
- } else {
10623
- flushWarnings();
10624
- }
10625
- const diagnostics = [
10626
- ...normalizeDocumentDiagnostics(source.diagnostics),
10627
- ...collectSmartArtComputedViewDiagnostics(computed),
10628
- ...normalizeRendererAdapterDiagnostics(adapted.diagnostics),
10629
- ...normalizeRendererWarningDiagnostics(rendererWarningEntries)
10630
- ];
10631
- const supportCoverage = buildSupportCoverage(computed, adapted.slides, diagnostics);
10632
- return { slides, diagnostics, supportCoverage };
10633
- } finally {
10634
- if (logLevel === "off") {
10635
- initWarningLogger("off");
10636
- }
10637
- resetTextMeasurer();
10638
- resetTextPathFontResolver();
10639
- resetFontUsageCollector();
10640
- resetFontMapping();
10641
- resetScriptFonts();
10815
+ slides.push({ slideNumber: slide.slideNumber, svg });
10642
10816
  }
10817
+ const rendererWarningEntries = [...context.warningLogger.getWarningEntries()];
10818
+ if (logLevel !== "off") {
10819
+ context.warningLogger.flushWarnings();
10820
+ }
10821
+ const diagnostics = [
10822
+ ...normalizeDocumentDiagnostics(source.diagnostics),
10823
+ ...collectSmartArtComputedViewDiagnostics(computed),
10824
+ ...normalizeRendererAdapterDiagnostics(adapted.diagnostics),
10825
+ ...normalizeRendererWarningDiagnostics(rendererWarningEntries)
10826
+ ];
10827
+ const supportCoverage = buildSupportCoverage(computed, adapted.slides, diagnostics);
10828
+ return { slides, diagnostics, supportCoverage };
10643
10829
  }
10644
10830
  function findScriptFontScheme(source) {
10645
10831
  const firstThemePartPath = source.slideMasters.find(
@@ -10812,6 +10998,9 @@ function shouldLoadSystemFonts(options) {
10812
10998
  async function convertPptxToSvg2(input, options) {
10813
10999
  return convertPptxToSvg(input, options, loadSystemFontSetup);
10814
11000
  }
11001
+ async function renderPptxSourceModelToSvg2(source, options) {
11002
+ return renderPptxSourceModelToSvg(source, options, loadSystemFontSetup);
11003
+ }
10815
11004
  async function convertPptxToPng(input, options) {
10816
11005
  const svgResult = await convertPptxToSvg2(input, {
10817
11006
  ...options,
@@ -11022,5 +11211,6 @@ async function initResvgWasm2(wasm) {
11022
11211
  getMappedFont,
11023
11212
  getWarningEntries,
11024
11213
  getWarningSummary,
11025
- initResvgWasm
11214
+ initResvgWasm,
11215
+ renderPptxSourceModelToSvg
11026
11216
  });