fix(pptx): preserve 8-digit hex (#RRGGBBAA) alpha in gradients and solid fills#60
Merged
karthikmudunuri merged 1 commit intoMay 29, 2026
Conversation
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Translucent fills written as 8-digit hex (
#RRGGBBAA) were serialized opaque. The cause was in the serializer's parser, not its emitter:parseFillnormalized#-prefixed colors throughhexBare, which truncates to 6 digits — so the alpha byte of#RRGGBBAA(and#RGBA) was discarded before it could reach<a:alpha>.gsLstXml,solidFillXml) already handledGradStop.alphacorrectly, so only alpha arriving viargba(...)survived. That's why a deck full of#RRGGBBAAgradient stops produced essentially one<a:alpha>in the whole file — a transparent fade rendered flat/opaque.Changes
pptxWriters.ts— newparseHexColorhelper (replacesnormaliseHex) extracts alpha from 4-digit (#RGBA) and 8-digit (#RRGGBBAA) hex.parseFillreturns it, so alpha now flows to gradient stops (viaparseStops), solid fills, and slide backgrounds.deckToPptx.ts—addShapemaps a solid fill's alpha to pptxgenjstransparency(0opaque …100transparent) 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#RRGGBBAAlinear stops, solid-fill alpha, and radial-gradient<a:gradFill><a:path path="circle">emission.Scope notes
synthesiseEmbeddedFonts+<p:embeddedFontLst>already fire fromdeck.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, sodeck.fontsis 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.300/500/600→ Light/Medium/SemiBold) is deferred; decks here use400/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 testinpackages/slidewise: 51 passed, 3 skipped (pre-existing). Typecheck (tsc -p tsconfig.lib.json) clean. (Lint viaeslint .fails to resolve@eslint/jsfrom the repo root — a pre-existing workspace setup issue unrelated to this change.)