contentpanel - Aushangworkflow um docx Vorlage erweitern
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import faces from '../fonts.json';
|
||||
|
||||
const buffers = new Map();
|
||||
|
||||
export async function loadTemplateFonts() {
|
||||
await Promise.all(faces.map(async (face) => {
|
||||
const response = await fetch(`/fonts/${face.file}`);
|
||||
if (!response.ok) throw new Error(`Schriftdatei fehlt: ${face.file} (HTTP ${response.status})`);
|
||||
const bytes = await response.arrayBuffer();
|
||||
// One set of OTF bytes for both native shaping and browser painting.
|
||||
const font = new FontFace(face.alias, bytes, { style: face.style, weight: '400' });
|
||||
await font.load();
|
||||
document.fonts.add(font);
|
||||
buffers.set(face.file, bytes);
|
||||
}));
|
||||
await document.fonts.ready;
|
||||
window.__betterofficeFontsReady = true;
|
||||
}
|
||||
|
||||
export const measurementFontProvider = {
|
||||
resolve(family, bold, italic) {
|
||||
const normalized = family.toLowerCase();
|
||||
// Empty paragraphs in this template inherit Calibri. Give those paragraphs
|
||||
// the same brand metrics instead of allowing synthetic line measurements.
|
||||
let face = faces.find((f) =>
|
||||
(f.alias.toLowerCase() === normalized || f.family.toLowerCase() === normalized ||
|
||||
(normalized === 'calibri' && f.alias === 'SuisseIntlLight')) &&
|
||||
f.style === (italic ? 'italic' : 'normal'));
|
||||
if (bold && !italic && face) face = faces.find((f) => f.alias === 'SuisseIntlSemiBold');
|
||||
if (!face || (bold && italic)) throw new Error(`Nicht unterstützte Schrift: ${family} (bold=${bold}, italic=${italic})`);
|
||||
return async () => {
|
||||
const bytes = buffers.get(face.file);
|
||||
if (!bytes) throw new Error(`Schrift wurde nicht geladen: ${face.file}`);
|
||||
return bytes;
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
/* Browser and native layout share the OTF buffers loaded by fonts.js. */
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: visible;
|
||||
background: #fff;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { DocxEditor } from '@betteroffice/docx-react';
|
||||
import { setGoogleFontsEnabled } from '@betteroffice/docx/utils';
|
||||
import '@betteroffice/docx-react/styles.css';
|
||||
import './renderer.css';
|
||||
import { loadTemplateFonts, measurementFontProvider } from './fonts';
|
||||
|
||||
setGoogleFontsEnabled(false); // The renderer is entirely local, including fonts.
|
||||
const reportError = error => { window.__betterofficeError ||= String(error?.stack || error); };
|
||||
window.addEventListener('error', event => reportError(event.error || event.message));
|
||||
window.addEventListener('unhandledrejection', event => reportError(event.reason));
|
||||
|
||||
try {
|
||||
await loadTemplateFonts();
|
||||
const response = await fetch('/input.docx');
|
||||
if (!response.ok) throw new Error(`DOCX HTTP ${response.status}`);
|
||||
const bytes = new Uint8Array(await response.arrayBuffer());
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<DocxEditor documentBuffer={bytes} measurementFontProvider={measurementFontProvider}
|
||||
ref={editor => { window.__betterofficeEditor = editor; }} onError={reportError}
|
||||
mode="viewing" showToolbar={false} showRuler={false} showZoomControl={false} />
|
||||
);
|
||||
} catch (error) {
|
||||
reportError(error);
|
||||
}
|
||||
Reference in New Issue
Block a user