Skip to content

fix(pptx): preserve picture source crops in svg exports - #88

Merged
ChristopherVR merged 2 commits into
ChristopherVR:mainfrom
yunfeizhu:fix/pptx-svg-picture-crop
Oct 16, 2026
Merged

ChristopherVR merged 2 commits into
ChristopherVR:mainfrom
yunfeizhu:fix/pptx-svg-picture-crop

Conversation

@yunfeizhu

@yunfeizhu yunfeizhu commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What does this change?

Fixes #87.

Apply picture source insets through a clipped SVG viewport so SVG exports retain the authored crop and destination frame. Preserve signed insets, image effects and outer transforms; leave uncropped images unchanged and fall back for invalid crop geometry.

Type of change

  • Bug fix (non-breaking)

Area

src/core/pptx/converter: shared headless SVG export, including the CLI.

Testing

  • Eleven focused regressions cover both image types, both crop axes, negative insets, invalid crops, transforms/effects and a real saved PPTX through the public CLI. Six fail on the original exporter.
  • bun run verify --base 260a953eabdd657fb744b8c4881d03f51da27a45: all 21 steps passed, including affected core/UI tests, builds, typechecks and viewer suites with React 18 compatibility.
  • Chromium pixel checks passed for crop selection, frame clipping, negative-inset padding and flips. All three e2e:local-only export regressions passed.
  • Previous fork CI passed for b5e8b9a353f1ceef73a13c4f987c75b4e6c28d40 with scope=changed.

Screenshots / recordings

Reproduction PPTX

Actual public CLI SVG output before and after the fix

Summary by CodeRabbit

  • New Features
    • SVG exports now preserve image and picture cropping, including inset adjustments on both axes and negative insets. The original image frame remains in place, while the visible source area reflects the crop.
    • Cropping is retained alongside rotation, flips and image effects, and when exporting a saved presentation through the command-line interface.
  • Bug Fixes
    • Images with zero or invalid crop geometry continue to export without unintended changes.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests Test-only change area: pptx PowerPoint engine size: M Fewer than 500 changed lines labels Oct 15, 2026
@pkg-pr-new

pkg-pr-new Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
  • ooxml-office-preview

    npm i https://pkg.pr.new/ooxml-core@1dd2eb5
    
    npm i https://pkg.pr.new/ooxml-ui@1dd2eb5
    

commit: 1dd2eb5

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⛔ Files ignored due to path filters: 1
  • src/core/pptx/__tests__/fixtures/svg-picture-crop.pptx is excluded by !**/*.pptx, !**/fixtures/**
⚙️ Run configuration
  • Configuration used: Repository: ChristopherVR/ooxml/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4365f5d8-4783-4dd3-8c55-3a1e2e600319
📥 Commits

Reviewing files that changed from the base of the PR and between 58dcb3b and 1dd2eb5.

⛔ Files ignored due to path filters: 1
  • src/core/pptx/__tests__/fixtures/svg-picture-crop.pptx is excluded by !**/*.pptx, !**/fixtures/**

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: ChristopherVR/ooxml/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 62520c16-8f5f-4982-8dc0-d674c2e3aeda
📥 Commits

Reviewing files that changed from the base of the PR and between 260a953 and b5e8b9a.

⛔ Files ignored due to path filters: 2
  • docs/bug-repros/pptx-svg-picture-crop.png is excluded by !**/*.png
  • src/core/pptx/__tests__/fixtures/svg-picture-crop.pptx is excluded by !**/*.pptx, !**/fixtures/**
📒 Files selected for processing: 3
  • src/core/pptx/converter/SvgExporter.crop.test.ts
  • src/core/pptx/converter/SvgExporter.ts
  • src/core/pptx/converter/svg-image-crop.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

📝 Walkthrough

The SVG exporter now wraps generated image markup in a viewport based on the image frame and crop insets. Zero or invalid crop geometry leaves the markup unchanged. Tests cover crop output for image and picture elements, preservation of transforms and effects, and export through the public CLI.

Fixed issue severity: <fixed_issue_severity>Low</fixed_issue_severity>

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to b5e8b

The SVG crop change is mergeable after normal checks; no blocking issue was identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed The changes address #87. SvgExporter applies wrapSvgImageCrop to exported image elements. The wrapper retains the destination frame and applies signed source insets through an SVG viewport. Tests …
Out of Scope Changes check Passed The changed files are limited to the shared PPTX SVG converter, its crop helper, and focused converter tests. The helper and tests directly support the crop-export fix in #87. No unrelated product are…
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly describes the main change: preserving picture source crops during SVG export. It is concise and specific.
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Bundle size

4 of 55 entry points changed size against main (3846a53):

Entry point Before (gzip) After (gzip) Change
ooxml-core/pptx 1181.2 kB 1181.5 kB +0.3 kB (+0.0%)
ooxml-core/pptx/automation 1196.9 kB 1197.2 kB +0.3 kB (+0.0%)
ooxml-core/pptx/cli 1071.4 kB 1071.7 kB +0.3 kB (+0.0%)
ooxml-core/pptx/converter 464.9 kB 465.1 kB +0.3 kB (+0.1%)
All entry points
Entry point Before (gzip) After (gzip) Change
ooxml-core 331.2 kB 331.2 kB 0
ooxml-core/automation 729.5 kB 729.5 kB 0
ooxml-core/automation/node 1.8 kB 1.8 kB 0
ooxml-core/chart 68.2 kB 68.2 kB 0
ooxml-core/collab 11.9 kB 11.9 kB 0
ooxml-core/color 4.1 kB 4.1 kB 0
ooxml-core/crypto 27.6 kB 27.6 kB 0
ooxml-core/diagram 157.5 kB 157.5 kB 0
ooxml-core/digest 12.3 kB 12.3 kB 0
ooxml-core/docx 213.1 kB 213.1 kB 0
ooxml-core/docx/embedded 140.1 kB 140.1 kB 0
ooxml-core/docx/layout 146.2 kB 146.2 kB 0
ooxml-core/docx/load 181.6 kB 181.6 kB 0
ooxml-core/docx/ui 124.2 kB 124.2 kB 0
ooxml-core/drawingml 14.5 kB 14.5 kB 0
ooxml-core/geometry 89.2 kB 89.2 kB 0
ooxml-core/i18n 5.6 kB 5.6 kB 0
ooxml-core/math 19.4 kB 19.4 kB 0
ooxml-core/opc 16.3 kB 16.3 kB 0
ooxml-core/pptx 1181.2 kB 1181.5 kB +0.3 kB (+0.0%)
ooxml-core/pptx/automation 1196.9 kB 1197.2 kB +0.3 kB (+0.0%)
ooxml-core/pptx/automation/schemas 127.5 kB 127.5 kB 0
ooxml-core/pptx/cli 1071.4 kB 1071.7 kB +0.3 kB (+0.0%)
ooxml-core/pptx/converter 464.9 kB 465.1 kB +0.3 kB (+0.1%)
ooxml-core/pptx/signature-node 14.3 kB 14.3 kB 0
ooxml-core/pptx/smartart-layouts 353.3 kB 353.3 kB 0
ooxml-core/pptx/ui 5.3 kB 5.3 kB 0
ooxml-core/ribbon 0.4 kB 0.4 kB 0
ooxml-core/teams 258.5 kB 258.5 kB 0
ooxml-core/text 5.9 kB 5.9 kB 0
ooxml-core/units 0.7 kB 0.7 kB 0
ooxml-core/visio 365.3 kB 365.3 kB 0
ooxml-core/visio/ui 340.5 kB 340.5 kB 0
ooxml-core/xlsx 410.3 kB 410.3 kB 0
ooxml-core/xlsx/collab 11.2 kB 11.2 kB 0
ooxml-core/xlsx/load 281.4 kB 281.4 kB 0
ooxml-core/xlsx/ui 364.5 kB 364.5 kB 0
ooxml-core/xml 3.9 kB 3.9 kB 0
ooxml-ui 212.7 kB 212.7 kB 0
ooxml-ui/controls 83.9 kB 83.9 kB 0
ooxml-ui/docx 331.4 kB 331.4 kB 0
ooxml-ui/icons 2.5 kB 2.5 kB 0
ooxml-ui/pptx 992.8 kB 992.8 kB 0
ooxml-ui/pptx/ai 22.5 kB 22.5 kB 0
ooxml-ui/pptx/dom 1001.6 kB 1001.6 kB 0
ooxml-ui/pptx/i18n 60.3 kB 60.3 kB 0
ooxml-ui/pptx/loader 1.5 kB 1.5 kB 0
ooxml-ui/pptx/theme 2.9 kB 2.9 kB 0
ooxml-ui/presence 7.7 kB 7.7 kB 0
ooxml-ui/smartart 9.0 kB 9.0 kB 0
ooxml-ui/suite 2.3 kB 2.3 kB 0
ooxml-ui/teams 206.7 kB 206.7 kB 0
ooxml-ui/theme 4.5 kB 4.5 kB 0
ooxml-ui/visio 299.0 kB 299.0 kB 0
ooxml-ui/xlsx 390.0 kB 390.0 kB 0

Each entry point with the files it imports statically, gzipped, before minification. Measured by scripts/bundle-size.mjs.

@ChristopherVR ChristopherVR left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks correct.

Wrapping the image in a nested <svg> whose viewBox selects the source rect keeps the destination frame, the outer transforms (rotation, flips) and the image-effect filters as they were, and signed insets give the expected padding. Uncropped pictures export byte-for-byte as before and invalid geometry falls back to the plain image. The CLI test on a saved deck is a nice touch.

Requests and notes:

  • Please drop docs/bug-repros/pptx-svg-picture-crop.png; screenshots are better kept in the PR description than committed under docs/.
  • Nit: the wrapper interpolates its numbers directly, while the rest of SvgExporter writes attributes through attrs(). Not a correctness issue.
  • Out of scope, for a follow-up: SVG export still ignores the stretch fill rect (a:stretch/a:fillRect), which the on-screen renderer applies together with the crop.

@yunfeizhu
yunfeizhu force-pushed the fix/pptx-svg-picture-crop branch from b5e8b9a to 58dcb3b Compare October 16, 2026 02:11
@github-actions github-actions Bot removed the documentation Improvements or additions to documentation label Oct 16, 2026
@yunfeizhu

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @ChristopherVR! Updated in 58dcb3b: removed the PNG from the commit and moved it to GitHub attachments in the PR and issue descriptions.

The .pptx fixture remains as input for the SVG/CLI regression tests. The PR still contains one commit.

@ChristopherVR
ChristopherVR merged commit 97c254c into ChristopherVR:main Oct 16, 2026
51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: pptx PowerPoint engine size: M Fewer than 500 changed lines tests Test-only change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SVG export ignores picture source cropping

2 participants