@openpresentation/opf-render 0.3.0 → 0.4.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/svg.js +19 -45
- package/package.json +2 -2
package/dist/svg.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fitList, fitRichText, composeSlide, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, textWidthMeasurer, fitText } from "@openpresentation/opf/composition";
|
|
1
|
+
import { layoutTable, fitList, fitRichText, composeSlide, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, textWidthMeasurer, fitText } from "@openpresentation/opf/composition";
|
|
2
2
|
import {
|
|
3
3
|
catalogs as bundledCatalogs,
|
|
4
4
|
validatePresentation
|
|
@@ -911,48 +911,22 @@ function renderTimeline(item, box, bound, options) {
|
|
|
911
911
|
|
|
912
912
|
function renderTable(item, box, bound, options) {
|
|
913
913
|
const scale = Math.min(bound.design.dimensions.width, bound.design.dimensions.height) / 720;
|
|
914
|
-
const
|
|
915
|
-
const columns = Array.isArray(table.columns) ? table.columns : [];
|
|
916
|
-
const rows = Array.isArray(table.rows) ? table.rows : [];
|
|
917
|
-
const allRows = columns.length ? [columns, ...rows] : rows;
|
|
918
|
-
const columnCount = Math.max(1, ...allRows.map((row) => Array.isArray(row) ? row.length : 1));
|
|
919
|
-
const rowCount = Math.max(1, allRows.length);
|
|
920
|
-
const cellWidth = box.width / columnCount;
|
|
921
|
-
const cellHeight = Math.min(54 * scale, box.height / rowCount);
|
|
914
|
+
const layout = layoutTable(item.value, box, {scale, minFontSize:(bound.composition ?? bound.geometry.composition).minFontSize, fontFamily:bound.design.fonts.body, textMeasurement:options.textMeasurement, path:item.path});
|
|
922
915
|
const children = [];
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
"stroke-width": 1,
|
|
938
|
-
...traceAttrs(options, cellPath)
|
|
939
|
-
}));
|
|
940
|
-
const rich = Array.isArray(cells[columnIndex]);
|
|
941
|
-
children.push((rich ? renderRichTextBox : renderTextBox)(rich ? cells[columnIndex] : flattenText(cells[columnIndex] ?? ""), {
|
|
942
|
-
x: x + 10 * scale,
|
|
943
|
-
y: y + 8 * scale,
|
|
944
|
-
width: Math.max(scale, cellWidth - 20 * scale),
|
|
945
|
-
height: Math.max(scale, cellHeight - 12 * scale)
|
|
946
|
-
}, bound, {
|
|
947
|
-
path: cellPath,
|
|
948
|
-
fontSize: 15,
|
|
949
|
-
fontFamily: bound.design.fonts.body,
|
|
950
|
-
fontWeight: rowIndex === 0 && columns.length ? 700 : 400,
|
|
951
|
-
fill: rowIndex === 0 && columns.length ? "#FFFFFF" : bound.design.colors.text,
|
|
952
|
-
options
|
|
953
|
-
}));
|
|
954
|
-
}
|
|
955
|
-
});
|
|
916
|
+
for (const row of layout.rows) for (const cell of row.cells) {
|
|
917
|
+
children.push(tag("rect", {
|
|
918
|
+
x: stableNumber(cell.box.x), y: stableNumber(cell.box.y),
|
|
919
|
+
width: stableNumber(cell.box.width), height: stableNumber(cell.box.height),
|
|
920
|
+
fill: cell.header ? bound.design.colors.primary : bound.design.colors.surface,
|
|
921
|
+
stroke: bound.design.colors.border, "stroke-width":1,
|
|
922
|
+
...traceAttrs(options, cell.path)
|
|
923
|
+
}));
|
|
924
|
+
children.push((cell.rich ? renderRichTextBox : renderTextBox)(cell.rich ? cell.value : flattenText(cell.value ?? ""), cell.textBox, bound, {
|
|
925
|
+
path:cell.path, fontSize:15, fontFamily:bound.design.fonts.body,
|
|
926
|
+
fontWeight:cell.header ? 700 : 400, textStyle:cell.textStyle, fit:cell.fit,
|
|
927
|
+
fill:cell.header ? "#FFFFFF" : bound.design.colors.text, options
|
|
928
|
+
}));
|
|
929
|
+
}
|
|
956
930
|
|
|
957
931
|
return tag("g", traceAttrs(options, item.path), children.join("\n"));
|
|
958
932
|
}
|
|
@@ -1168,7 +1142,7 @@ function renderEmbeddedFonts(fonts = []) {
|
|
|
1168
1142
|
|
|
1169
1143
|
function renderRichTextBox(value, box, bound, config) {
|
|
1170
1144
|
const scale=Math.min(bound.design.dimensions.width,bound.design.dimensions.height)/720;
|
|
1171
|
-
const fit=fitRichText(value,box,config.fontSize*scale,((bound.composition??bound.geometry.composition).minFontSize??16)*scale,{style:{fontFamily:config.fontFamily,fontWeight:config.fontWeight??400,path:config.path},textMeasurement:config.options.textMeasurement});
|
|
1145
|
+
const fit=config.fit??fitRichText(value,box,config.fontSize*scale,((bound.composition??bound.geometry.composition).minFontSize??16)*scale,{style:{fontFamily:config.fontFamily,fontWeight:config.fontWeight??400,path:config.path},textMeasurement:config.options.textMeasurement});
|
|
1172
1146
|
if(fit.overflow){const diagnostic={code:'text-overflow',path:config.path,message:'Mixed-style text exceeds its cell at the minimum font size.'};reportDiagnostic(diagnostic,config.options);if((bound.composition??bound.geometry.composition).overflow==='error')throw new OPFRenderError('layout-overflow',diagnostic.message,{issues:[diagnostic]});}
|
|
1173
1147
|
return renderRichLines(value,fit,box,bound,config);
|
|
1174
1148
|
}
|
|
@@ -1196,8 +1170,8 @@ function renderRichLines(value,fit,box,bound,config) {
|
|
|
1196
1170
|
|
|
1197
1171
|
function renderTextBox(text, box, bound, config) {
|
|
1198
1172
|
const scale = Math.min(bound.design.dimensions.width, bound.design.dimensions.height) / 720;
|
|
1199
|
-
const style = resolveTextStyle({fontFamily:config.fontFamily,fontWeight:config.fontWeight ?? 400,italic:config.italic ?? false,path:config.path},config.options.textMeasurement);
|
|
1200
|
-
const fit = fitText(String(text ?? ""), box, config.fontSize * scale,
|
|
1173
|
+
const style = config.textStyle ?? resolveTextStyle({fontFamily:config.fontFamily,fontWeight:config.fontWeight ?? 400,italic:config.italic ?? false,path:config.path},config.options.textMeasurement);
|
|
1174
|
+
const fit = config.fit ?? fitText(String(text ?? ""), box, config.fontSize * scale,
|
|
1201
1175
|
((bound.composition ?? bound.geometry.composition).minFontSize ?? 16) * scale, textWidthMeasurer(style,config.options.textMeasurement));
|
|
1202
1176
|
if (fit.overflow) {
|
|
1203
1177
|
const diagnostic = { code: "text-overflow", path: config.path,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpresentation/opf-render",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Deterministic local OPF renderer for SVG, PNG, and PDF output.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@expo-google-fonts/roboto": "^0.4.3",
|
|
73
73
|
"@expo-google-fonts/roboto-mono": "^0.4.2",
|
|
74
74
|
"@expo-google-fonts/tinos": "0.4.2",
|
|
75
|
-
"@openpresentation/opf": "^0.
|
|
75
|
+
"@openpresentation/opf": "^0.6.0",
|
|
76
76
|
"@resvg/resvg-js": "^2.6.2",
|
|
77
77
|
"fontkit": "^2.0.4",
|
|
78
78
|
"pdf-lib": "^1.17.1",
|