Skip to content

fix(pptx): preserve 8-digit hex (#RRGGBBAA) alpha in gradients and solid fills#60

Merged
karthikmudunuri merged 1 commit into
mainfrom
karthikmudunuri/serializedeck-gradient-font-fixes
May 29, 2026
Merged

fix(pptx): preserve 8-digit hex (#RRGGBBAA) alpha in gradients and solid fills#60
karthikmudunuri merged 1 commit into
mainfrom
karthikmudunuri/serializedeck-gradient-font-fixes

Conversation

@karthikmudunuri
Copy link
Copy Markdown
Member

What & why

Translucent fills written as 8-digit hex (#RRGGBBAA) were serialized opaque. The cause was in the serializer's parser, not its emitter:

  • parseFill normalized #-prefixed colors through hexBare, which truncates to 6 digits — so the alpha byte of #RRGGBBAA (and #RGBA) was discarded before it could reach <a:alpha>.
  • The emission side (gsLstXml, solidFillXml) already handled GradStop.alpha correctly, so only alpha arriving via rgba(...) survived. That's why a deck full of #RRGGBBAA gradient stops produced essentially one <a:alpha> in the whole file — a transparent fade rendered flat/opaque.

Changes

  • pptxWriters.ts — new parseHexColor helper (replaces normaliseHex) extracts alpha from 4-digit (#RGBA) and 8-digit (#RRGGBBAA) hex. parseFill returns it, so alpha now flows to gradient stops (via parseStops), solid fills, and slide backgrounds.
  • deckToPptx.tsaddShape maps a solid fill's alpha to pptxgenjs transparency (0 opaque … 100 transparent) so flat translucent shape fills no longer render opaque. (Gradient/image fills already took the synth path.)
  • synth-writers.test.ts — 3 new tests: per-stop alpha from #RRGGBBAA linear stops, solid-fill alpha, and radial-gradient <a:gradFill><a:path path="circle"> emission.

Scope notes

  • Radial gradients were already emitted correctly — added a test to lock it in.
  • Font embedding is not changed: synthesiseEmbeddedFonts + <p:embeddedFontLst> already fire from deck.fonts. The "fonts fall back to Calibri" symptom for template-built decks is a font-sourcing issue (the template JSON carries family names but no binaries, so deck.fonts is empty) and can't be fixed inside the serializer — it needs the template pipeline to attach font binaries, or the brand fonts installed in the render container.
  • Numeric-weight → named-face mapping (300/500/600 → Light/Medium/SemiBold) is deferred; decks here use 400/700, which map cleanly to the bold flag.

Release

Includes a changeset (@textcortex/slidewise: patch) so the release workflow versions and publishes it.

Testing

pnpm test in packages/slidewise: 51 passed, 3 skipped (pre-existing). Typecheck (tsc -p tsconfig.lib.json) clean. (Lint via eslint . fails to resolve @eslint/js from the repo root — a pre-existing workspace setup issue unrelated to this change.)

…lid fills

parseFill truncated #RRGGBBAA / #RGBA colors to 6 digits via hexBare,
dropping per-stop and solid-fill alpha before it reached <a:alpha>.
Now extracts alpha from 4- and 8-digit hex: gradient stops carry their
<a:alpha>, and solid shape fills map alpha to pptxgenjs transparency.
Adds tests for gradient-stop alpha, solid-fill alpha, and radial-gradient
<a:path> emission.
@karthikmudunuri karthikmudunuri merged commit d2529c3 into main May 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant