[Bug][Slides] Negative connector extent from FPresentation.save() is rejected by PPTX export
Before you submit this issue
- This is reproducible with an official Slides snapshot and the official Node exchange exporter.
- I searched the public Issues and PRs for
OOXML extent, negative Slide width/height, connector transform, and PPTX connector export, but found no matching report.
Affected packages and versions
@univerjs-pro/slides:1.0.0-rc.0@univerjs-pro/slides-ui:1.0.0-rc.0@univerjs-pro/exchange-node:1.0.0-rc.0@univerjs/core:1.0.0-rc.0- Node.js:
22.22.1
Reproduction snapshot
A sanitized full ISlideData snapshot is available here:
https://gist.github.com/zsq1234/ed2c3962127fb42a34b2e29e0bbac44f
The DSH RPC wrapper and session identifiers were removed; only the presentation snapshot is included. The top-level presentation ID was replaced with negative-connector-extent-repro.
The failing element in that snapshot is:
{
"slideId": "GX5wTC",
"slideName": "月度趋势",
"element": {
"id": "VpGNav",
"type": "connector",
"transform": {
"left": 365.45454545454544,
"top": 387.39857666666666,
"width": 68.36363636363637,
"height": -43.125713333333294,
"rotation": 0,
"flipX": false,
"flipY": false
},
"connectorData": {
"stroke": {
"lineStrokeType": 2,
"color": "#2563EB",
"width": 3
},
"shapeType": "line"
}
}
}This is an upward-sloping connector. Its signed height appears to represent the direction from one endpoint to the other.
Steps to reproduce
- Load the attached snapshot as a Slide presentation.
- Obtain the snapshot through the official Facade API:
const presentation = univerAPI.getActivePresentation();
const snapshot = presentation.save();- Export that official snapshot with the official Node exporter:
await exportToFile(snapshot, outputPath, {
type: UniverInstanceType.UNIVER_SLIDE,
format: ExchangeFormat.PPTX,
});Actual behavior
The export fails with:
validation error: slide page GX5wTC element VpGNav transform height must produce an OOXML extent between 0 and 2147483647 EMU, got -43.125713333333294 pt (-547697 EMU)FPresentation.save() preserves the signed connector height, while @univerjs-pro/exchange-node rejects it as an unsigned OOXML extent.
Expected behavior
A snapshot returned by the official FPresentation.save() API should be accepted by the official exchange-node PPTX exporter.
For a connector with a negative height, the exporter or an earlier canonicalization boundary could preserve the same bounds and direction by converting it to an OOXML-compatible transform, for example:
top = top + height;
height = Math.abs(height);
flipY = !flipY;The equivalent normalization applies to a negative width using left and flipX.
Additional context
This looks like a contract mismatch between the Slides connector model and the PPTX exporter rather than an arbitrary invalid consumer snapshot: signed width/height are useful for encoding connector endpoint direction, but OOXML a:ext values must be non-negative.
Could the connector serializer canonicalize signed transforms before validating/writing OOXML extents, or should the Slides model/save path guarantee canonical positive extents?
Source: dream-num/univer