pptx-glimpse 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +133 -64
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +132 -63
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1043,12 +1043,109 @@ function measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa) {
|
|
|
1043
1043
|
return totalWidth;
|
|
1044
1044
|
}
|
|
1045
1045
|
|
|
1046
|
+
// src/warning-logger.ts
|
|
1047
|
+
var PREFIX = "[pptx-glimpse]";
|
|
1048
|
+
var currentLevel = "off";
|
|
1049
|
+
var entries = [];
|
|
1050
|
+
var featureCounts = /* @__PURE__ */ new Map();
|
|
1051
|
+
function initWarningLogger(level) {
|
|
1052
|
+
currentLevel = level;
|
|
1053
|
+
entries = [];
|
|
1054
|
+
featureCounts.clear();
|
|
1055
|
+
}
|
|
1056
|
+
function warn(feature, message, context) {
|
|
1057
|
+
if (currentLevel === "off") return;
|
|
1058
|
+
entries.push({ feature, message, ...context !== void 0 && { context } });
|
|
1059
|
+
const existing = featureCounts.get(feature);
|
|
1060
|
+
if (existing) {
|
|
1061
|
+
existing.count++;
|
|
1062
|
+
} else {
|
|
1063
|
+
featureCounts.set(feature, { message, count: 1 });
|
|
1064
|
+
}
|
|
1065
|
+
if (currentLevel === "debug") {
|
|
1066
|
+
const ctx = context ? ` (${context})` : "";
|
|
1067
|
+
console.warn(`${PREFIX} SKIP: ${feature} - ${message}${ctx}`);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
function debug(feature, message, context) {
|
|
1071
|
+
if (currentLevel !== "debug") return;
|
|
1072
|
+
entries.push({ feature, message, ...context !== void 0 && { context } });
|
|
1073
|
+
const existing = featureCounts.get(feature);
|
|
1074
|
+
if (existing) {
|
|
1075
|
+
existing.count++;
|
|
1076
|
+
} else {
|
|
1077
|
+
featureCounts.set(feature, { message, count: 1 });
|
|
1078
|
+
}
|
|
1079
|
+
const ctx = context ? ` (${context})` : "";
|
|
1080
|
+
console.warn(`${PREFIX} DEBUG: ${feature} - ${message}${ctx}`);
|
|
1081
|
+
}
|
|
1082
|
+
function getWarningSummary() {
|
|
1083
|
+
const features = [];
|
|
1084
|
+
for (const [feature, { message, count }] of featureCounts) {
|
|
1085
|
+
features.push({ feature, message, count });
|
|
1086
|
+
}
|
|
1087
|
+
return { totalCount: entries.length, features };
|
|
1088
|
+
}
|
|
1089
|
+
function flushWarnings() {
|
|
1090
|
+
const summary = getWarningSummary();
|
|
1091
|
+
if (currentLevel !== "off" && summary.features.length > 0) {
|
|
1092
|
+
console.warn(`${PREFIX} Summary: ${summary.features.length} unsupported feature(s) detected`);
|
|
1093
|
+
for (const { feature, count } of summary.features) {
|
|
1094
|
+
console.warn(` - ${feature}: ${count} occurrence(s)`);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
entries = [];
|
|
1098
|
+
featureCounts.clear();
|
|
1099
|
+
return summary;
|
|
1100
|
+
}
|
|
1101
|
+
function getWarningEntries() {
|
|
1102
|
+
return entries;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
// src/font/cjk-font-fallback.ts
|
|
1106
|
+
var import_node_os = require("os");
|
|
1107
|
+
var MACOS_FALLBACKS = {
|
|
1108
|
+
// ゴシック系
|
|
1109
|
+
"Noto Sans JP": ["Hiragino Sans", "Hiragino Kaku Gothic ProN"],
|
|
1110
|
+
"Noto Sans CJK JP": ["Hiragino Sans", "Hiragino Kaku Gothic ProN"],
|
|
1111
|
+
// 明朝系
|
|
1112
|
+
"Noto Serif CJK JP": ["Hiragino Mincho ProN"]
|
|
1113
|
+
};
|
|
1114
|
+
var WINDOWS_FALLBACKS = {
|
|
1115
|
+
// ゴシック系
|
|
1116
|
+
"Noto Sans JP": ["Yu Gothic", "Meiryo", "MS Gothic"],
|
|
1117
|
+
"Noto Sans CJK JP": ["Yu Gothic", "Meiryo", "MS Gothic"],
|
|
1118
|
+
// 明朝系
|
|
1119
|
+
"Noto Serif CJK JP": ["Yu Mincho", "MS Mincho"]
|
|
1120
|
+
};
|
|
1121
|
+
var EMPTY = [];
|
|
1122
|
+
var cachedFallbacks = null;
|
|
1123
|
+
function getFallbackMap() {
|
|
1124
|
+
if (cachedFallbacks) return cachedFallbacks;
|
|
1125
|
+
const os = (0, import_node_os.platform)();
|
|
1126
|
+
switch (os) {
|
|
1127
|
+
case "darwin":
|
|
1128
|
+
cachedFallbacks = MACOS_FALLBACKS;
|
|
1129
|
+
break;
|
|
1130
|
+
case "win32":
|
|
1131
|
+
cachedFallbacks = WINDOWS_FALLBACKS;
|
|
1132
|
+
break;
|
|
1133
|
+
default:
|
|
1134
|
+
cachedFallbacks = {};
|
|
1135
|
+
}
|
|
1136
|
+
return cachedFallbacks;
|
|
1137
|
+
}
|
|
1138
|
+
function getCjkFallbackFonts(mappedFontName) {
|
|
1139
|
+
return getFallbackMap()[mappedFontName] ?? EMPTY;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1046
1142
|
// src/font/opentype-text-measurer.ts
|
|
1047
1143
|
var PX_PER_PT2 = 96 / 72;
|
|
1048
1144
|
var BOLD_FACTOR2 = 1.05;
|
|
1049
1145
|
var OpentypeTextMeasurer = class {
|
|
1050
1146
|
fonts;
|
|
1051
1147
|
defaultFont;
|
|
1148
|
+
warnedFonts = /* @__PURE__ */ new Set();
|
|
1052
1149
|
/**
|
|
1053
1150
|
* @param fonts - フォント名 → opentype.js Font オブジェクトのマップ
|
|
1054
1151
|
* @param defaultFont - フォールバックフォント(省略可)
|
|
@@ -1098,6 +1195,14 @@ var OpentypeTextMeasurer = class {
|
|
|
1098
1195
|
if (mapped) {
|
|
1099
1196
|
const mappedFont = this.fonts.get(mapped);
|
|
1100
1197
|
if (mappedFont) return mappedFont;
|
|
1198
|
+
for (const fallback of getCjkFallbackFonts(mapped)) {
|
|
1199
|
+
const fallbackFont = this.fonts.get(fallback);
|
|
1200
|
+
if (fallbackFont) return fallbackFont;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
if (!this.warnedFonts.has(name)) {
|
|
1204
|
+
this.warnedFonts.add(name);
|
|
1205
|
+
warn("font.notFound", `Font not found: "${name}"`);
|
|
1101
1206
|
}
|
|
1102
1207
|
return null;
|
|
1103
1208
|
}
|
|
@@ -1105,19 +1210,31 @@ var OpentypeTextMeasurer = class {
|
|
|
1105
1210
|
|
|
1106
1211
|
// src/font/system-font-loader.ts
|
|
1107
1212
|
var import_node_fs = require("fs");
|
|
1108
|
-
var
|
|
1213
|
+
var import_node_os2 = require("os");
|
|
1109
1214
|
var import_node_path = require("path");
|
|
1110
1215
|
var FONT_EXTENSIONS = /* @__PURE__ */ new Set([".ttf", ".otf"]);
|
|
1111
|
-
var CJK_TTC_PATTERNS = [
|
|
1216
|
+
var CJK_TTC_PATTERNS = [
|
|
1217
|
+
"NotoSansCJK",
|
|
1218
|
+
"NotoSerifCJK",
|
|
1219
|
+
// macOS
|
|
1220
|
+
"Hiragino",
|
|
1221
|
+
"\u30D2\u30E9\u30AE\u30CE",
|
|
1222
|
+
// Windows
|
|
1223
|
+
"YuGoth",
|
|
1224
|
+
"YuMin",
|
|
1225
|
+
"meiryo",
|
|
1226
|
+
"msgothic",
|
|
1227
|
+
"msmincho"
|
|
1228
|
+
];
|
|
1112
1229
|
var cachedPaths = null;
|
|
1113
1230
|
var cachedAdditionalDirs = null;
|
|
1114
1231
|
function getSystemFontDirs() {
|
|
1115
|
-
const os = (0,
|
|
1232
|
+
const os = (0, import_node_os2.platform)();
|
|
1116
1233
|
switch (os) {
|
|
1117
1234
|
case "linux":
|
|
1118
1235
|
return ["/usr/share/fonts", "/usr/local/share/fonts"];
|
|
1119
1236
|
case "darwin":
|
|
1120
|
-
return ["/System/Library/Fonts", "/Library/Fonts", (0, import_node_path.join)((0,
|
|
1237
|
+
return ["/System/Library/Fonts", "/Library/Fonts", (0, import_node_path.join)((0, import_node_os2.homedir)(), "Library/Fonts")];
|
|
1121
1238
|
case "win32":
|
|
1122
1239
|
return ["C:\\Windows\\Fonts"];
|
|
1123
1240
|
default:
|
|
@@ -1125,7 +1242,7 @@ function getSystemFontDirs() {
|
|
|
1125
1242
|
}
|
|
1126
1243
|
}
|
|
1127
1244
|
function isCjkTtc(name) {
|
|
1128
|
-
const lower = name.toLowerCase();
|
|
1245
|
+
const lower = name.normalize("NFC").toLowerCase();
|
|
1129
1246
|
return lower.endsWith(".ttc") && CJK_TTC_PATTERNS.some((p) => lower.includes(p.toLowerCase()));
|
|
1130
1247
|
}
|
|
1131
1248
|
function walk(dir, result) {
|
|
@@ -1163,6 +1280,7 @@ function collectFontFilePaths(additionalDirs) {
|
|
|
1163
1280
|
var DefaultTextPathFontResolver = class {
|
|
1164
1281
|
fonts;
|
|
1165
1282
|
defaultFont;
|
|
1283
|
+
warnedFonts = /* @__PURE__ */ new Set();
|
|
1166
1284
|
constructor(fonts, defaultFont) {
|
|
1167
1285
|
this.fonts = fonts;
|
|
1168
1286
|
this.defaultFont = defaultFont ?? null;
|
|
@@ -1180,6 +1298,12 @@ var DefaultTextPathFontResolver = class {
|
|
|
1180
1298
|
const font = this.findFont(jpanFallback);
|
|
1181
1299
|
if (font) return font;
|
|
1182
1300
|
}
|
|
1301
|
+
for (const name of [fontFamily, fontFamilyEa, jpanFallback]) {
|
|
1302
|
+
if (name && !this.warnedFonts.has(name)) {
|
|
1303
|
+
this.warnedFonts.add(name);
|
|
1304
|
+
warn("font.notFound", `Font not found: "${name}"`);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1183
1307
|
return this.defaultFont;
|
|
1184
1308
|
}
|
|
1185
1309
|
findFont(name) {
|
|
@@ -1189,6 +1313,10 @@ var DefaultTextPathFontResolver = class {
|
|
|
1189
1313
|
if (mapped) {
|
|
1190
1314
|
const mappedFont = this.fonts.get(mapped);
|
|
1191
1315
|
if (mappedFont) return mappedFont;
|
|
1316
|
+
for (const fallback of getCjkFallbackFonts(mapped)) {
|
|
1317
|
+
const fallbackFont = this.fonts.get(fallback);
|
|
1318
|
+
if (fallbackFont) return fallbackFont;
|
|
1319
|
+
}
|
|
1192
1320
|
}
|
|
1193
1321
|
return null;
|
|
1194
1322
|
}
|
|
@@ -1621,65 +1749,6 @@ async function svgToPng(svgString, options) {
|
|
|
1621
1749
|
};
|
|
1622
1750
|
}
|
|
1623
1751
|
|
|
1624
|
-
// src/warning-logger.ts
|
|
1625
|
-
var PREFIX = "[pptx-glimpse]";
|
|
1626
|
-
var currentLevel = "off";
|
|
1627
|
-
var entries = [];
|
|
1628
|
-
var featureCounts = /* @__PURE__ */ new Map();
|
|
1629
|
-
function initWarningLogger(level) {
|
|
1630
|
-
currentLevel = level;
|
|
1631
|
-
entries = [];
|
|
1632
|
-
featureCounts.clear();
|
|
1633
|
-
}
|
|
1634
|
-
function warn(feature, message, context) {
|
|
1635
|
-
if (currentLevel === "off") return;
|
|
1636
|
-
entries.push({ feature, message, ...context !== void 0 && { context } });
|
|
1637
|
-
const existing = featureCounts.get(feature);
|
|
1638
|
-
if (existing) {
|
|
1639
|
-
existing.count++;
|
|
1640
|
-
} else {
|
|
1641
|
-
featureCounts.set(feature, { message, count: 1 });
|
|
1642
|
-
}
|
|
1643
|
-
if (currentLevel === "debug") {
|
|
1644
|
-
const ctx = context ? ` (${context})` : "";
|
|
1645
|
-
console.warn(`${PREFIX} SKIP: ${feature} - ${message}${ctx}`);
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
function debug(feature, message, context) {
|
|
1649
|
-
if (currentLevel !== "debug") return;
|
|
1650
|
-
entries.push({ feature, message, ...context !== void 0 && { context } });
|
|
1651
|
-
const existing = featureCounts.get(feature);
|
|
1652
|
-
if (existing) {
|
|
1653
|
-
existing.count++;
|
|
1654
|
-
} else {
|
|
1655
|
-
featureCounts.set(feature, { message, count: 1 });
|
|
1656
|
-
}
|
|
1657
|
-
const ctx = context ? ` (${context})` : "";
|
|
1658
|
-
console.warn(`${PREFIX} DEBUG: ${feature} - ${message}${ctx}`);
|
|
1659
|
-
}
|
|
1660
|
-
function getWarningSummary() {
|
|
1661
|
-
const features = [];
|
|
1662
|
-
for (const [feature, { message, count }] of featureCounts) {
|
|
1663
|
-
features.push({ feature, message, count });
|
|
1664
|
-
}
|
|
1665
|
-
return { totalCount: entries.length, features };
|
|
1666
|
-
}
|
|
1667
|
-
function flushWarnings() {
|
|
1668
|
-
const summary = getWarningSummary();
|
|
1669
|
-
if (currentLevel !== "off" && summary.features.length > 0) {
|
|
1670
|
-
console.warn(`${PREFIX} Summary: ${summary.features.length} unsupported feature(s) detected`);
|
|
1671
|
-
for (const { feature, count } of summary.features) {
|
|
1672
|
-
console.warn(` - ${feature}: ${count} occurrence(s)`);
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
entries = [];
|
|
1676
|
-
featureCounts.clear();
|
|
1677
|
-
return summary;
|
|
1678
|
-
}
|
|
1679
|
-
function getWarningEntries() {
|
|
1680
|
-
return entries;
|
|
1681
|
-
}
|
|
1682
|
-
|
|
1683
1752
|
// src/color/color-transforms.ts
|
|
1684
1753
|
function applyColorTransforms(color, node) {
|
|
1685
1754
|
let { hex, alpha } = color;
|
package/dist/index.d.cts
CHANGED
|
@@ -125,6 +125,7 @@ interface OpentypeFont {
|
|
|
125
125
|
declare class OpentypeTextMeasurer implements TextMeasurer {
|
|
126
126
|
private fonts;
|
|
127
127
|
private defaultFont;
|
|
128
|
+
private warnedFonts;
|
|
128
129
|
/**
|
|
129
130
|
* @param fonts - フォント名 → opentype.js Font オブジェクトのマップ
|
|
130
131
|
* @param defaultFont - フォールバックフォント(省略可)
|
package/dist/index.d.ts
CHANGED
|
@@ -125,6 +125,7 @@ interface OpentypeFont {
|
|
|
125
125
|
declare class OpentypeTextMeasurer implements TextMeasurer {
|
|
126
126
|
private fonts;
|
|
127
127
|
private defaultFont;
|
|
128
|
+
private warnedFonts;
|
|
128
129
|
/**
|
|
129
130
|
* @param fonts - フォント名 → opentype.js Font オブジェクトのマップ
|
|
130
131
|
* @param defaultFont - フォールバックフォント(省略可)
|
package/dist/index.js
CHANGED
|
@@ -1007,12 +1007,109 @@ function measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa) {
|
|
|
1007
1007
|
return totalWidth;
|
|
1008
1008
|
}
|
|
1009
1009
|
|
|
1010
|
+
// src/warning-logger.ts
|
|
1011
|
+
var PREFIX = "[pptx-glimpse]";
|
|
1012
|
+
var currentLevel = "off";
|
|
1013
|
+
var entries = [];
|
|
1014
|
+
var featureCounts = /* @__PURE__ */ new Map();
|
|
1015
|
+
function initWarningLogger(level) {
|
|
1016
|
+
currentLevel = level;
|
|
1017
|
+
entries = [];
|
|
1018
|
+
featureCounts.clear();
|
|
1019
|
+
}
|
|
1020
|
+
function warn(feature, message, context) {
|
|
1021
|
+
if (currentLevel === "off") return;
|
|
1022
|
+
entries.push({ feature, message, ...context !== void 0 && { context } });
|
|
1023
|
+
const existing = featureCounts.get(feature);
|
|
1024
|
+
if (existing) {
|
|
1025
|
+
existing.count++;
|
|
1026
|
+
} else {
|
|
1027
|
+
featureCounts.set(feature, { message, count: 1 });
|
|
1028
|
+
}
|
|
1029
|
+
if (currentLevel === "debug") {
|
|
1030
|
+
const ctx = context ? ` (${context})` : "";
|
|
1031
|
+
console.warn(`${PREFIX} SKIP: ${feature} - ${message}${ctx}`);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
function debug(feature, message, context) {
|
|
1035
|
+
if (currentLevel !== "debug") return;
|
|
1036
|
+
entries.push({ feature, message, ...context !== void 0 && { context } });
|
|
1037
|
+
const existing = featureCounts.get(feature);
|
|
1038
|
+
if (existing) {
|
|
1039
|
+
existing.count++;
|
|
1040
|
+
} else {
|
|
1041
|
+
featureCounts.set(feature, { message, count: 1 });
|
|
1042
|
+
}
|
|
1043
|
+
const ctx = context ? ` (${context})` : "";
|
|
1044
|
+
console.warn(`${PREFIX} DEBUG: ${feature} - ${message}${ctx}`);
|
|
1045
|
+
}
|
|
1046
|
+
function getWarningSummary() {
|
|
1047
|
+
const features = [];
|
|
1048
|
+
for (const [feature, { message, count }] of featureCounts) {
|
|
1049
|
+
features.push({ feature, message, count });
|
|
1050
|
+
}
|
|
1051
|
+
return { totalCount: entries.length, features };
|
|
1052
|
+
}
|
|
1053
|
+
function flushWarnings() {
|
|
1054
|
+
const summary = getWarningSummary();
|
|
1055
|
+
if (currentLevel !== "off" && summary.features.length > 0) {
|
|
1056
|
+
console.warn(`${PREFIX} Summary: ${summary.features.length} unsupported feature(s) detected`);
|
|
1057
|
+
for (const { feature, count } of summary.features) {
|
|
1058
|
+
console.warn(` - ${feature}: ${count} occurrence(s)`);
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
entries = [];
|
|
1062
|
+
featureCounts.clear();
|
|
1063
|
+
return summary;
|
|
1064
|
+
}
|
|
1065
|
+
function getWarningEntries() {
|
|
1066
|
+
return entries;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
// src/font/cjk-font-fallback.ts
|
|
1070
|
+
import { platform } from "os";
|
|
1071
|
+
var MACOS_FALLBACKS = {
|
|
1072
|
+
// ゴシック系
|
|
1073
|
+
"Noto Sans JP": ["Hiragino Sans", "Hiragino Kaku Gothic ProN"],
|
|
1074
|
+
"Noto Sans CJK JP": ["Hiragino Sans", "Hiragino Kaku Gothic ProN"],
|
|
1075
|
+
// 明朝系
|
|
1076
|
+
"Noto Serif CJK JP": ["Hiragino Mincho ProN"]
|
|
1077
|
+
};
|
|
1078
|
+
var WINDOWS_FALLBACKS = {
|
|
1079
|
+
// ゴシック系
|
|
1080
|
+
"Noto Sans JP": ["Yu Gothic", "Meiryo", "MS Gothic"],
|
|
1081
|
+
"Noto Sans CJK JP": ["Yu Gothic", "Meiryo", "MS Gothic"],
|
|
1082
|
+
// 明朝系
|
|
1083
|
+
"Noto Serif CJK JP": ["Yu Mincho", "MS Mincho"]
|
|
1084
|
+
};
|
|
1085
|
+
var EMPTY = [];
|
|
1086
|
+
var cachedFallbacks = null;
|
|
1087
|
+
function getFallbackMap() {
|
|
1088
|
+
if (cachedFallbacks) return cachedFallbacks;
|
|
1089
|
+
const os = platform();
|
|
1090
|
+
switch (os) {
|
|
1091
|
+
case "darwin":
|
|
1092
|
+
cachedFallbacks = MACOS_FALLBACKS;
|
|
1093
|
+
break;
|
|
1094
|
+
case "win32":
|
|
1095
|
+
cachedFallbacks = WINDOWS_FALLBACKS;
|
|
1096
|
+
break;
|
|
1097
|
+
default:
|
|
1098
|
+
cachedFallbacks = {};
|
|
1099
|
+
}
|
|
1100
|
+
return cachedFallbacks;
|
|
1101
|
+
}
|
|
1102
|
+
function getCjkFallbackFonts(mappedFontName) {
|
|
1103
|
+
return getFallbackMap()[mappedFontName] ?? EMPTY;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1010
1106
|
// src/font/opentype-text-measurer.ts
|
|
1011
1107
|
var PX_PER_PT2 = 96 / 72;
|
|
1012
1108
|
var BOLD_FACTOR2 = 1.05;
|
|
1013
1109
|
var OpentypeTextMeasurer = class {
|
|
1014
1110
|
fonts;
|
|
1015
1111
|
defaultFont;
|
|
1112
|
+
warnedFonts = /* @__PURE__ */ new Set();
|
|
1016
1113
|
/**
|
|
1017
1114
|
* @param fonts - フォント名 → opentype.js Font オブジェクトのマップ
|
|
1018
1115
|
* @param defaultFont - フォールバックフォント(省略可)
|
|
@@ -1062,6 +1159,14 @@ var OpentypeTextMeasurer = class {
|
|
|
1062
1159
|
if (mapped) {
|
|
1063
1160
|
const mappedFont = this.fonts.get(mapped);
|
|
1064
1161
|
if (mappedFont) return mappedFont;
|
|
1162
|
+
for (const fallback of getCjkFallbackFonts(mapped)) {
|
|
1163
|
+
const fallbackFont = this.fonts.get(fallback);
|
|
1164
|
+
if (fallbackFont) return fallbackFont;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
if (!this.warnedFonts.has(name)) {
|
|
1168
|
+
this.warnedFonts.add(name);
|
|
1169
|
+
warn("font.notFound", `Font not found: "${name}"`);
|
|
1065
1170
|
}
|
|
1066
1171
|
return null;
|
|
1067
1172
|
}
|
|
@@ -1069,14 +1174,26 @@ var OpentypeTextMeasurer = class {
|
|
|
1069
1174
|
|
|
1070
1175
|
// src/font/system-font-loader.ts
|
|
1071
1176
|
import { existsSync, readdirSync } from "fs";
|
|
1072
|
-
import { homedir, platform } from "os";
|
|
1177
|
+
import { homedir, platform as platform2 } from "os";
|
|
1073
1178
|
import { extname, join } from "path";
|
|
1074
1179
|
var FONT_EXTENSIONS = /* @__PURE__ */ new Set([".ttf", ".otf"]);
|
|
1075
|
-
var CJK_TTC_PATTERNS = [
|
|
1180
|
+
var CJK_TTC_PATTERNS = [
|
|
1181
|
+
"NotoSansCJK",
|
|
1182
|
+
"NotoSerifCJK",
|
|
1183
|
+
// macOS
|
|
1184
|
+
"Hiragino",
|
|
1185
|
+
"\u30D2\u30E9\u30AE\u30CE",
|
|
1186
|
+
// Windows
|
|
1187
|
+
"YuGoth",
|
|
1188
|
+
"YuMin",
|
|
1189
|
+
"meiryo",
|
|
1190
|
+
"msgothic",
|
|
1191
|
+
"msmincho"
|
|
1192
|
+
];
|
|
1076
1193
|
var cachedPaths = null;
|
|
1077
1194
|
var cachedAdditionalDirs = null;
|
|
1078
1195
|
function getSystemFontDirs() {
|
|
1079
|
-
const os =
|
|
1196
|
+
const os = platform2();
|
|
1080
1197
|
switch (os) {
|
|
1081
1198
|
case "linux":
|
|
1082
1199
|
return ["/usr/share/fonts", "/usr/local/share/fonts"];
|
|
@@ -1089,7 +1206,7 @@ function getSystemFontDirs() {
|
|
|
1089
1206
|
}
|
|
1090
1207
|
}
|
|
1091
1208
|
function isCjkTtc(name) {
|
|
1092
|
-
const lower = name.toLowerCase();
|
|
1209
|
+
const lower = name.normalize("NFC").toLowerCase();
|
|
1093
1210
|
return lower.endsWith(".ttc") && CJK_TTC_PATTERNS.some((p) => lower.includes(p.toLowerCase()));
|
|
1094
1211
|
}
|
|
1095
1212
|
function walk(dir, result) {
|
|
@@ -1127,6 +1244,7 @@ function collectFontFilePaths(additionalDirs) {
|
|
|
1127
1244
|
var DefaultTextPathFontResolver = class {
|
|
1128
1245
|
fonts;
|
|
1129
1246
|
defaultFont;
|
|
1247
|
+
warnedFonts = /* @__PURE__ */ new Set();
|
|
1130
1248
|
constructor(fonts, defaultFont) {
|
|
1131
1249
|
this.fonts = fonts;
|
|
1132
1250
|
this.defaultFont = defaultFont ?? null;
|
|
@@ -1144,6 +1262,12 @@ var DefaultTextPathFontResolver = class {
|
|
|
1144
1262
|
const font = this.findFont(jpanFallback);
|
|
1145
1263
|
if (font) return font;
|
|
1146
1264
|
}
|
|
1265
|
+
for (const name of [fontFamily, fontFamilyEa, jpanFallback]) {
|
|
1266
|
+
if (name && !this.warnedFonts.has(name)) {
|
|
1267
|
+
this.warnedFonts.add(name);
|
|
1268
|
+
warn("font.notFound", `Font not found: "${name}"`);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1147
1271
|
return this.defaultFont;
|
|
1148
1272
|
}
|
|
1149
1273
|
findFont(name) {
|
|
@@ -1153,6 +1277,10 @@ var DefaultTextPathFontResolver = class {
|
|
|
1153
1277
|
if (mapped) {
|
|
1154
1278
|
const mappedFont = this.fonts.get(mapped);
|
|
1155
1279
|
if (mappedFont) return mappedFont;
|
|
1280
|
+
for (const fallback of getCjkFallbackFonts(mapped)) {
|
|
1281
|
+
const fallbackFont = this.fonts.get(fallback);
|
|
1282
|
+
if (fallbackFont) return fallbackFont;
|
|
1283
|
+
}
|
|
1156
1284
|
}
|
|
1157
1285
|
return null;
|
|
1158
1286
|
}
|
|
@@ -1584,65 +1712,6 @@ async function svgToPng(svgString, options) {
|
|
|
1584
1712
|
};
|
|
1585
1713
|
}
|
|
1586
1714
|
|
|
1587
|
-
// src/warning-logger.ts
|
|
1588
|
-
var PREFIX = "[pptx-glimpse]";
|
|
1589
|
-
var currentLevel = "off";
|
|
1590
|
-
var entries = [];
|
|
1591
|
-
var featureCounts = /* @__PURE__ */ new Map();
|
|
1592
|
-
function initWarningLogger(level) {
|
|
1593
|
-
currentLevel = level;
|
|
1594
|
-
entries = [];
|
|
1595
|
-
featureCounts.clear();
|
|
1596
|
-
}
|
|
1597
|
-
function warn(feature, message, context) {
|
|
1598
|
-
if (currentLevel === "off") return;
|
|
1599
|
-
entries.push({ feature, message, ...context !== void 0 && { context } });
|
|
1600
|
-
const existing = featureCounts.get(feature);
|
|
1601
|
-
if (existing) {
|
|
1602
|
-
existing.count++;
|
|
1603
|
-
} else {
|
|
1604
|
-
featureCounts.set(feature, { message, count: 1 });
|
|
1605
|
-
}
|
|
1606
|
-
if (currentLevel === "debug") {
|
|
1607
|
-
const ctx = context ? ` (${context})` : "";
|
|
1608
|
-
console.warn(`${PREFIX} SKIP: ${feature} - ${message}${ctx}`);
|
|
1609
|
-
}
|
|
1610
|
-
}
|
|
1611
|
-
function debug(feature, message, context) {
|
|
1612
|
-
if (currentLevel !== "debug") return;
|
|
1613
|
-
entries.push({ feature, message, ...context !== void 0 && { context } });
|
|
1614
|
-
const existing = featureCounts.get(feature);
|
|
1615
|
-
if (existing) {
|
|
1616
|
-
existing.count++;
|
|
1617
|
-
} else {
|
|
1618
|
-
featureCounts.set(feature, { message, count: 1 });
|
|
1619
|
-
}
|
|
1620
|
-
const ctx = context ? ` (${context})` : "";
|
|
1621
|
-
console.warn(`${PREFIX} DEBUG: ${feature} - ${message}${ctx}`);
|
|
1622
|
-
}
|
|
1623
|
-
function getWarningSummary() {
|
|
1624
|
-
const features = [];
|
|
1625
|
-
for (const [feature, { message, count }] of featureCounts) {
|
|
1626
|
-
features.push({ feature, message, count });
|
|
1627
|
-
}
|
|
1628
|
-
return { totalCount: entries.length, features };
|
|
1629
|
-
}
|
|
1630
|
-
function flushWarnings() {
|
|
1631
|
-
const summary = getWarningSummary();
|
|
1632
|
-
if (currentLevel !== "off" && summary.features.length > 0) {
|
|
1633
|
-
console.warn(`${PREFIX} Summary: ${summary.features.length} unsupported feature(s) detected`);
|
|
1634
|
-
for (const { feature, count } of summary.features) {
|
|
1635
|
-
console.warn(` - ${feature}: ${count} occurrence(s)`);
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
entries = [];
|
|
1639
|
-
featureCounts.clear();
|
|
1640
|
-
return summary;
|
|
1641
|
-
}
|
|
1642
|
-
function getWarningEntries() {
|
|
1643
|
-
return entries;
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1646
1715
|
// src/color/color-transforms.ts
|
|
1647
1716
|
function applyColorTransforms(color, node) {
|
|
1648
1717
|
let { hex, alpha } = color;
|
package/package.json
CHANGED