feat(ppt): pictures from the BLIP store, real slide size, slide names#610
feat(ppt): pictures from the BLIP store, real slide size, slide names#610andiwand wants to merge 3 commits into
Conversation
Parse the StyleTextPropAtom ([MS-PPT] 2.9.44) that follows each text atom — in the drawing's ClientTextbox as well as the outline (SlideListWithText) — and split slide text into styled spans carrying bold, italic, underline, font size, font name (FontCollection) and explicit sRGB colors. Replaces the flat 11pt placeholder; unformatted text defaults to 18pt, approximating the unread master text styles. Paragraph-level runs are skipped field-by-field via their PFMasks; paragraphs store their first run's style so empty paragraphs keep their height. Scheme-indexed colors and master-inherited formatting remain open (documented in AGENTS.md). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9Z3kyUaHNkJacAEggevHH
Resolve each shape's pib (picture shape) or fillBlip (picture fill, the LibreOffice pattern) property through the OfficeArtBStoreContainer and the /Pictures delay stream, and emit JPEG/PNG BLIPs as image elements under the shape's frame, served as in-memory files. Background shapes (OfficeArtFSP.fBackground) get a full-slide anchor and render below the other shapes. The drawing's optional non-grouped shape ([MS-ODRAW] 2.2.13) is now read too - picture fills live there. Also: slide size from the DocumentAtom instead of hardcoded 10x7.5in, and slide_name returns "Slide N". WMF/EMF/PICT/DIB/TIFF BLIPs and pictures on master slides remain open (documented in AGENTS.md). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9Z3kyUaHNkJacAEggevHH
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 43863a237f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| [[nodiscard]] std::string image_href( | ||
| [[maybe_unused]] const ElementIdentifier element_id) const override { | ||
| return {}; |
There was a problem hiding this comment.
Assign PPT images a non-empty resource path
When callers set HtmlConfig::embed_images = false, the generic image renderer asks the resource locator for a URL based on image.href(). Returning an empty string here makes every PPT image resource use an empty path, so the generated HTML gets src="" and bring_offline() cannot write distinct image assets. This only shows up in non-embedded image output, but that is a supported renderer configuration.
Useful? React with 👍 / 👎.
With HtmlConfig::embed_images = false the generic renderer uses
image.href() as the resource path, so the empty href produced src=""
and bring_offline could not write distinct image assets. Pictures have
no container path in the file; synthesize one from the one-based BLIP
store index plus the extension matching the image bytes
("Pictures/<index>.png|.jpg"). Addresses review feedback on #610.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AEvWWwe1EyeWH7ANHoAvPH
7a2bd37 to
97ebb8e
Compare
🤖 Generated with Claude Code
Stacked on #609 (same files; base is
feat/ppt-character-formatting).Adds pictures to the legacy
.pptdecoder, plus two small fidelity wins from the AGENTS.md open-work list.Pictures
OfficeArtFOPTis now parsed forpib(real picture shapes) andfillBlip(picture fills — how LibreOffice-exported.pptplaces pictures); both are one-based indexes into theOfficeArtBStoreContainerof the document's drawing group.OfficeArtFBSElocates its BLIP in the/Pictures(delay) stream atfoDelay(embedded BLIPs are handled too). JPEG and PNG BLIPs become animageelement under the shape's frame, served to the renderer as an in-memoryodr::File→ rendered as a base64<img>. WMF/EMF/PICT/DIB/TIFF are skipped (documented open work).fBackground(OfficeArtFSP) get a full-slide anchor when they carry none and are ordered before the slide's other shapes so they render underneath.Micro-wins
DocumentAtom(master units → inches) instead of the hardcoded 10"×7.5" —style-various-1.pptrenders at its real 11.02"×8.27" size (open-work §2.1).slide_namereturns "Slide N" in presentation order (open-work §2.6).Validation & tests
OldMs.ppt_style_variousextended: slide 6 ("title6 – background image") now asserts a leading full-slide frame holding an image element whose bytes are the PNG from/Pictures; frame count 12 → 13. AllOldMs.*and pptHtmlOutputTestspass.Note: the
2025-09-11photo-deck fixture keeps rendering without photos — its pictures live on per-slide masters, which are skipped entirely (documented open work).https://claude.ai/code/session_01R9Z3kyUaHNkJacAEggevHH