pptx-glimpse 2.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.
@@ -0,0 +1,25 @@
1
+ // ../renderer/src/png/render-svg.ts
2
+ import { Resvg } from "@resvg/resvg-wasm";
3
+ function renderSvgToPng(svgString, options) {
4
+ const resvgOptions = {};
5
+ if (options?.width) {
6
+ resvgOptions.fitTo = { mode: "width", value: options.width };
7
+ } else if (options?.height) {
8
+ resvgOptions.fitTo = { mode: "height", value: options.height };
9
+ }
10
+ const fontBuffers = options?.fontBuffers;
11
+ if (fontBuffers && fontBuffers.length > 0) {
12
+ resvgOptions.font = { fontBuffers };
13
+ }
14
+ const resvg = new Resvg(svgString, resvgOptions);
15
+ const rendered = resvg.render();
16
+ return {
17
+ png: new Uint8Array(rendered.asPng()),
18
+ width: rendered.width,
19
+ height: rendered.height
20
+ };
21
+ }
22
+
23
+ export {
24
+ renderSvgToPng
25
+ };
@@ -0,0 +1,125 @@
1
+ import {
2
+ buildOpentypeSetupFromState,
3
+ buildReverseMapping,
4
+ createFontMapping,
5
+ createOpentypeSetupState,
6
+ getCachedSystemOpentypeSetup,
7
+ parseFontBuffer,
8
+ registerParsedFont,
9
+ setCachedSystemOpentypeSetup,
10
+ toArrayBuffer,
11
+ tryLoadOpentype
12
+ } from "./chunk-PGCREQQU.js";
13
+
14
+ // ../renderer/src/font/opentype-system-helpers.ts
15
+ import { readFile } from "fs/promises";
16
+
17
+ // ../renderer/src/font/system-font-loader.ts
18
+ import { existsSync, readdirSync } from "fs";
19
+ import { homedir, platform } from "os";
20
+ import { extname, join } from "path";
21
+ var FONT_EXTENSIONS = /* @__PURE__ */ new Set([".ttf", ".otf"]);
22
+ var CJK_TTC_PATTERNS = [
23
+ "NotoSansCJK",
24
+ "NotoSerifCJK",
25
+ // macOS
26
+ "Hiragino",
27
+ "\u30D2\u30E9\u30AE\u30CE",
28
+ // Windows
29
+ "YuGoth",
30
+ "YuMin",
31
+ "meiryo",
32
+ "msgothic",
33
+ "msmincho"
34
+ ];
35
+ var cachedPaths = null;
36
+ var cachedAdditionalDirs = null;
37
+ var cachedSkipSystemFonts = null;
38
+ function getSystemFontDirs() {
39
+ const os = platform();
40
+ if (os === "linux") return ["/usr/share/fonts", "/usr/local/share/fonts"];
41
+ if (os === "darwin") {
42
+ return ["/System/Library/Fonts", "/Library/Fonts", join(homedir(), "Library/Fonts")];
43
+ }
44
+ if (os === "win32") return ["C:\\Windows\\Fonts"];
45
+ return [];
46
+ }
47
+ function isCjkTtc(name) {
48
+ const lower = name.normalize("NFC").toLowerCase();
49
+ return lower.endsWith(".ttc") && CJK_TTC_PATTERNS.some((p) => lower.includes(p.toLowerCase()));
50
+ }
51
+ function walk(dir, result) {
52
+ if (!existsSync(dir)) return;
53
+ try {
54
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
55
+ const fullPath = join(dir, entry.name);
56
+ if (entry.isDirectory()) {
57
+ walk(fullPath, result);
58
+ } else if (FONT_EXTENSIONS.has(extname(entry.name).toLowerCase()) || isCjkTtc(entry.name)) {
59
+ result.push(fullPath);
60
+ }
61
+ }
62
+ } catch {
63
+ }
64
+ }
65
+ function collectFontFilePaths(additionalDirs, skipSystemFonts = false) {
66
+ const dirs = additionalDirs ?? [];
67
+ const dirsKey = dirs.join("\0");
68
+ const cachedKey = cachedAdditionalDirs?.join("\0") ?? null;
69
+ if (cachedPaths !== null && dirsKey === cachedKey && cachedSkipSystemFonts === skipSystemFonts) {
70
+ return cachedPaths;
71
+ }
72
+ const allDirs = skipSystemFonts ? dirs : [...getSystemFontDirs(), ...dirs];
73
+ const result = [];
74
+ for (const dir of allDirs) {
75
+ walk(dir, result);
76
+ }
77
+ result.sort((a, b) => a.localeCompare(b));
78
+ cachedPaths = result;
79
+ cachedAdditionalDirs = dirs;
80
+ cachedSkipSystemFonts = skipSystemFonts;
81
+ return result;
82
+ }
83
+
84
+ // ../renderer/src/font/opentype-system-helpers.ts
85
+ function buildCacheKey(additionalFontDirs, fontMapping, skipSystemFonts = false) {
86
+ const dirsKey = additionalFontDirs ? [...additionalFontDirs].sort().join("\0") : "";
87
+ const mappingKey = fontMapping ? JSON.stringify(fontMapping, Object.keys(fontMapping).sort()) : "";
88
+ return `${dirsKey}
89
+ ${mappingKey}
90
+ ${skipSystemFonts}`;
91
+ }
92
+ async function createOpentypeSetupFromSystem(additionalFontDirs, fontMapping, skipSystemFonts = false) {
93
+ const key = buildCacheKey(additionalFontDirs, fontMapping, skipSystemFonts);
94
+ const cached = getCachedSystemOpentypeSetup(key);
95
+ if (cached !== void 0) {
96
+ return cached;
97
+ }
98
+ const opentype = await tryLoadOpentype();
99
+ if (!opentype) return null;
100
+ const fontFilePaths = collectFontFilePaths(additionalFontDirs, skipSystemFonts);
101
+ if (fontFilePaths.length === 0) return null;
102
+ const mapping = createFontMapping(fontMapping);
103
+ const reverseMap = buildReverseMapping(mapping);
104
+ const state = createOpentypeSetupState();
105
+ for (const filePath of fontFilePaths) {
106
+ try {
107
+ const data = await readFile(filePath);
108
+ const arrayBuffer = toArrayBuffer(data);
109
+ const fonts = parseFontBuffer(arrayBuffer, opentype);
110
+ for (const font of fonts) {
111
+ registerParsedFont(font, reverseMap, state);
112
+ }
113
+ } catch {
114
+ }
115
+ }
116
+ const setup = buildOpentypeSetupFromState(state, mapping);
117
+ if (setup === null) return null;
118
+ setCachedSystemOpentypeSetup(key, setup);
119
+ return setup;
120
+ }
121
+
122
+ export {
123
+ collectFontFilePaths,
124
+ createOpentypeSetupFromSystem
125
+ };
@@ -0,0 +1,83 @@
1
+ import {
2
+ DEFAULT_OUTPUT_WIDTH,
3
+ convertPptxToSvg,
4
+ renderPptxSourceModelToSvg
5
+ } from "./chunk-NMAO44T7.js";
6
+
7
+ // src/converter.ts
8
+ async function convertPptxToSvg2(input, options) {
9
+ return convertPptxToSvg(input, options, loadSystemFontSetup);
10
+ }
11
+ async function renderPptxSourceModelToSvg2(source, options) {
12
+ return renderPptxSourceModelToSvg(source, options, loadSystemFontSetup);
13
+ }
14
+ async function convertPptxToPng(input, options) {
15
+ const svgResult = await convertPptxToSvg2(input, {
16
+ ...options,
17
+ textOutput: "path"
18
+ });
19
+ const width = options?.width ?? DEFAULT_OUTPUT_WIDTH;
20
+ const height = options?.height;
21
+ const fontBuffers = await loadPngFontBuffers(options);
22
+ const slides = [];
23
+ for (const { slideNumber, svg } of svgResult.slides) {
24
+ const pngResult = await convertSvgToPng(svg, { width, height, fontBuffers });
25
+ slides.push({
26
+ slideNumber,
27
+ png: toPlainUint8Array(pngResult.png),
28
+ width: pngResult.width,
29
+ height: pngResult.height
30
+ });
31
+ }
32
+ return {
33
+ slides,
34
+ diagnostics: svgResult.diagnostics,
35
+ supportCoverage: svgResult.supportCoverage
36
+ };
37
+ }
38
+ var loadSystemFontSetup = async (options) => {
39
+ if (!shouldLoadSystemFonts(options)) {
40
+ return null;
41
+ }
42
+ const { createOpentypeSetupFromSystem } = await import(
43
+ /* @vite-ignore */
44
+ "./node-E6UXPQSQ.js"
45
+ );
46
+ return createOpentypeSetupFromSystem(
47
+ options?.fontDirs,
48
+ options?.fontMapping,
49
+ options?.skipSystemFonts
50
+ );
51
+ };
52
+ async function loadPngFontBuffers(options) {
53
+ if (options?.fonts !== void 0) {
54
+ return options.fonts.map((font) => toUint8Array(font.data));
55
+ }
56
+ if (!shouldLoadSystemFonts(options)) {
57
+ return [];
58
+ }
59
+ const { loadFontBuffersFromSystem } = await import(
60
+ /* @vite-ignore */
61
+ "./node-font-loader-OE3OLNDI.js"
62
+ );
63
+ return loadFontBuffersFromSystem(options?.fontDirs, options?.skipSystemFonts);
64
+ }
65
+ async function convertSvgToPng(svg, options) {
66
+ const { svgToPng } = await import("./png-IONMVVDQ.js");
67
+ return svgToPng(svg, options);
68
+ }
69
+ function shouldLoadSystemFonts(options) {
70
+ return options?.skipSystemFonts !== true || (options?.fontDirs?.length ?? 0) > 0;
71
+ }
72
+ function toUint8Array(data) {
73
+ return data instanceof Uint8Array ? data : new Uint8Array(data);
74
+ }
75
+ function toPlainUint8Array(data) {
76
+ return new Uint8Array(data);
77
+ }
78
+
79
+ export {
80
+ convertPptxToSvg2 as convertPptxToSvg,
81
+ renderPptxSourceModelToSvg2 as renderPptxSourceModelToSvg,
82
+ convertPptxToPng
83
+ };
@@ -0,0 +1,141 @@
1
+ import {
2
+ createComputedView,
3
+ readPptx
4
+ } from "./chunk-NMAO44T7.js";
5
+
6
+ // src/font/font-collector.ts
7
+ var DEFAULT_THEME_FONTS = {
8
+ majorLatin: "Calibri",
9
+ minorLatin: "Calibri"
10
+ };
11
+ function collectUsedFonts(input) {
12
+ const source = readPptx(input);
13
+ const defaultFontScheme = findDefaultThemeFontScheme(source);
14
+ const computed = createComputedView(source);
15
+ const fonts = /* @__PURE__ */ new Set();
16
+ collectThemeFonts(defaultFontScheme, fonts);
17
+ const visitedTemplateParts = /* @__PURE__ */ new Set();
18
+ for (const slide of computed.slides) {
19
+ const slideFontScheme = findThemeFontScheme(source, slide.themePartPath) ?? defaultFontScheme;
20
+ const templateElementsByPart = /* @__PURE__ */ new Map();
21
+ for (const element of slide.elements) {
22
+ if (element.sourceLayer === "slide") {
23
+ collectFontsFromElements([element], fonts, slideFontScheme);
24
+ continue;
25
+ }
26
+ const key = `${element.sourceLayer}:${element.sourcePartPath}`;
27
+ const elements = templateElementsByPart.get(key);
28
+ if (elements) {
29
+ elements.push(element);
30
+ } else {
31
+ templateElementsByPart.set(key, [element]);
32
+ }
33
+ }
34
+ for (const [key, elements] of templateElementsByPart) {
35
+ if (visitedTemplateParts.has(key)) continue;
36
+ visitedTemplateParts.add(key);
37
+ collectFontsFromElements(elements, fonts, slideFontScheme);
38
+ }
39
+ }
40
+ return {
41
+ theme: {
42
+ majorFont: defaultFontScheme.majorLatin,
43
+ minorFont: defaultFontScheme.minorLatin,
44
+ majorFontEa: defaultFontScheme.majorEastAsian ?? null,
45
+ minorFontEa: defaultFontScheme.minorEastAsian ?? null,
46
+ majorFontCs: defaultFontScheme.majorComplexScript ?? null,
47
+ minorFontCs: defaultFontScheme.minorComplexScript ?? null
48
+ },
49
+ fonts: [...fonts].sort()
50
+ };
51
+ }
52
+ function findDefaultThemeFontScheme(source) {
53
+ const firstThemePartPath = source.slideMasters.find(
54
+ (master) => master.themePartPath !== void 0
55
+ )?.themePartPath;
56
+ const scheme = findThemeFontScheme(source, firstThemePartPath) ?? source.themes[0]?.fontScheme;
57
+ return applyDefaultThemeFonts(scheme);
58
+ }
59
+ function findThemeFontScheme(source, themePartPath) {
60
+ if (themePartPath === void 0) return void 0;
61
+ const scheme = source.themes.find((theme) => theme.partPath === themePartPath)?.fontScheme;
62
+ return scheme !== void 0 ? applyDefaultThemeFonts(scheme) : void 0;
63
+ }
64
+ function applyDefaultThemeFonts(scheme) {
65
+ return {
66
+ ...DEFAULT_THEME_FONTS,
67
+ ...scheme
68
+ };
69
+ }
70
+ function collectThemeFonts(fontScheme, fonts) {
71
+ addFont(fonts, fontScheme.majorLatin, fontScheme);
72
+ addFont(fonts, fontScheme.minorLatin, fontScheme);
73
+ addFont(fonts, fontScheme.majorEastAsian, fontScheme);
74
+ addFont(fonts, fontScheme.minorEastAsian, fontScheme);
75
+ addFont(fonts, fontScheme.majorComplexScript, fontScheme);
76
+ addFont(fonts, fontScheme.minorComplexScript, fontScheme);
77
+ addFont(fonts, fontScheme.majorJapanese, fontScheme);
78
+ addFont(fonts, fontScheme.minorJapanese, fontScheme);
79
+ }
80
+ function collectFontsFromElements(elements, fonts, fontScheme) {
81
+ for (const el of elements) {
82
+ switch (el.kind) {
83
+ case "shape":
84
+ if (el.textBody) collectFontsFromTextBody(el.textBody, fonts, fontScheme);
85
+ break;
86
+ case "group":
87
+ collectFontsFromElements(el.children, fonts, fontScheme);
88
+ break;
89
+ case "table":
90
+ for (const row of el.table.rows) {
91
+ for (const cell of row.cells) {
92
+ if (cell.textBody) collectFontsFromTextBody(cell.textBody, fonts, fontScheme);
93
+ }
94
+ }
95
+ break;
96
+ case "connector":
97
+ case "image":
98
+ case "chart":
99
+ case "smartArt":
100
+ case "raw":
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ function collectFontsFromTextBody(textBody, fonts, fontScheme) {
106
+ for (const para of textBody.paragraphs) {
107
+ addFont(fonts, para.properties?.bulletFont, fontScheme);
108
+ for (const run of para.runs) {
109
+ addFont(fonts, run.properties?.typeface, fontScheme);
110
+ addFont(fonts, run.properties?.typefaceEa, fontScheme);
111
+ addFont(fonts, run.properties?.typefaceCs, fontScheme);
112
+ }
113
+ }
114
+ }
115
+ function addFont(fonts, font, fontScheme) {
116
+ const resolved = resolveThemeFontAlias(font, fontScheme);
117
+ if (resolved) fonts.add(resolved);
118
+ }
119
+ function resolveThemeFontAlias(font, fontScheme) {
120
+ if (font === void 0) return void 0;
121
+ switch (font) {
122
+ case "+mj-lt":
123
+ return fontScheme.majorLatin;
124
+ case "+mn-lt":
125
+ return fontScheme.minorLatin;
126
+ case "+mj-ea":
127
+ return fontScheme.majorEastAsian ?? fontScheme.majorJapanese;
128
+ case "+mn-ea":
129
+ return fontScheme.minorEastAsian ?? fontScheme.minorJapanese;
130
+ case "+mj-cs":
131
+ return fontScheme.majorComplexScript;
132
+ case "+mn-cs":
133
+ return fontScheme.minorComplexScript;
134
+ default:
135
+ return font.startsWith("+mj-") || font.startsWith("+mn-") ? void 0 : font;
136
+ }
137
+ }
138
+
139
+ export {
140
+ collectUsedFonts
141
+ };