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/browser.cjs +3058 -737
- package/dist/browser.d.cts +77 -8
- package/dist/browser.d.ts +77 -8
- package/dist/browser.js +486 -23
- package/dist/{chunk-KMSN55AE.js → chunk-NMAO44T7.js} +2242 -522
- package/dist/{chunk-2AYNMYMC.js → chunk-PGCREQQU.js} +134 -113
- package/dist/{chunk-MWMHSSAD.js → chunk-WAMKNW47.js} +4 -3
- package/dist/chunk-XGCLQP2P.js +83 -0
- package/dist/chunk-ZZKN4U5J.js +141 -0
- package/dist/cli.cjs +11214 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +195 -0
- package/dist/font-collector-BYuaCG-o.d.cts +547 -0
- package/dist/font-collector-BYuaCG-o.d.ts +547 -0
- package/dist/index.cjs +752 -562
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +12 -76
- package/dist/{node-6KTAWUIB.js → node-E6UXPQSQ.js} +2 -2
- package/dist/{node-font-loader-274G445U.js → node-font-loader-OE3OLNDI.js} +2 -2
- package/package.json +9 -6
- package/dist/font-collector-DYooJP6L.d.cts +0 -1345
- package/dist/font-collector-DYooJP6L.d.ts +0 -1345
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
|
|
1072
|
-
currentMapping
|
|
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
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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
|
|
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
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
3107
|
+
if (entries.length === 0) return "";
|
|
3056
3108
|
const ENTRY_HEIGHT = 20;
|
|
3057
3109
|
if (position === "r" || position === "l") {
|
|
3058
|
-
const totalH =
|
|
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 <
|
|
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(
|
|
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(
|
|
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 =
|
|
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 <
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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 =
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
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 =
|
|
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
|
-
|
|
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,
|
|
5220
|
-
const styles = buildStyleAttrs(props, fontScale, fonts);
|
|
5221
|
-
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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 ?
|
|
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 +=
|
|
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 =
|
|
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) :
|
|
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) :
|
|
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(
|
|
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(
|
|
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(
|
|
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, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
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"),
|
|
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,
|
|
6639
|
-
length: parseEnumValueWithDefault(length,
|
|
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
|
|
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
|
|
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
|
|
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 ===
|
|
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 ===
|
|
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
|
|
9591
|
-
var
|
|
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
|
|
9768
|
+
const entries = unzipPackage(input);
|
|
9598
9769
|
const diagnostics = [];
|
|
9599
|
-
const contentTypes = readContentTypes(
|
|
9600
|
-
const relationships = readRelationships(
|
|
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
|
|
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
|
-
|
|
9787
|
+
entries,
|
|
9617
9788
|
relationships,
|
|
9618
9789
|
contentTypes.overrides,
|
|
9619
9790
|
diagnostics
|
|
9620
9791
|
);
|
|
9621
|
-
const hierarchy = readSlideHierarchy(
|
|
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(
|
|
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(
|
|
9813
|
+
const part = parsePartRoot(entries, slidePath, "sld", diagnostics, true);
|
|
9643
9814
|
if (part === void 0) continue;
|
|
9644
|
-
const layoutPath = resolveSingleRel(relationships, slidePath,
|
|
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(
|
|
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(
|
|
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,
|
|
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(
|
|
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(
|
|
9712
|
-
const bytes =
|
|
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
|
|
9958
|
+
const entries = /* @__PURE__ */ new Map();
|
|
9764
9959
|
for (const [path, bytes] of Object.entries(unzipped)) {
|
|
9765
9960
|
if (path.endsWith("/")) continue;
|
|
9766
|
-
|
|
9961
|
+
entries.set(path, bytes);
|
|
9767
9962
|
}
|
|
9768
|
-
return
|
|
9963
|
+
return entries;
|
|
9769
9964
|
}
|
|
9770
|
-
function readContentTypes(
|
|
9771
|
-
const bytes =
|
|
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(
|
|
9985
|
+
function readRelationships(entries) {
|
|
9791
9986
|
const result = [];
|
|
9792
|
-
for (const [path, bytes] of
|
|
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(
|
|
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 =
|
|
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 !==
|
|
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
|
-
|
|
10586
|
-
|
|
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
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
);
|
|
10597
|
-
|
|
10598
|
-
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
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
|
-
|
|
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
|
});
|