Skip to content

fix(ooxml): an xlsx fill shows its colour, and a font its toggles - #935

Merged
andiwand merged 5 commits into
mainfrom
fix/xlsx-cell-style-read
Sep 28, 2026
Merged

andiwand merged 5 commits into
mainfrom
fix/xlsx-cell-style-read

Conversation

@andiwand

@andiwand andiwand commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Step 1 of the cell-formatting plan: the xlsx reader reads what the writer will write.

Change

  • A pattern fill paints fgColor. The reader took bgColor, so a solid fill showed the colour of the pattern background: cyan in place of #DEE6EF in multiline.xlsx, for example. A pattern of none, or no pattern, now paints nothing.
  • A theme colour resolves from the a:clrScheme of the theme that the workbook relates to by type, counted lt1, dk1, lt2, dk2, accent1… as SpreadsheetML counts them, and tint moves the lightness of any colour ([ECMA-376] 18.8.19).
  • A font reads i, u and strike, and val="0" on b is not bold.
  • Horizontal alignment reads left and right, and vertical alignment reads top and bottom. Before, both read center only.
  • util/color_util gathers the colour math that html, pdf and ooxml each had a copy of: to_byte (four copies), the sRGB transfer (two), Oklab from html::dark_fill and Hsl from the xlsx tint. Each module keeps only its own rule on top. The xlsx theme and the pptx colour scheme share ooxml::read_drawing_rgb_color.

Proof

  • New OoxmlSpreadsheetStyle tests on inline styles.xml and theme strings. The tint results are the values Excel shows: accent 1 #4472C4 "Darker 25%" is #2F5597, and "Lighter 80%" is #DAE3F3.
  • The full suite passes (1871 tests), with new ColorUtil, Hsl and Oklab tests. The refactor leaves the full HTML output, public and private, byte-identical to the pinned reference output.
  • Headless Chrome, old against new, with LibreOffice as the reference: the fills of multiline.xlsx now match LibreOffice, and sample.xlsx shows its purple theme header and title, where the header was white text on white before.

Reference output

8 public and 45 private files change, all xlsx. Both pins advance: public f0cea38, private 0ebf950.

@andiwand
andiwand force-pushed the docs/plan-cell-formatting branch from 1f273cf to 5fbc691 Compare September 28, 2026 18:21
Base automatically changed from docs/plan-cell-formatting to main September 28, 2026 18:22
andiwand and others added 3 commits September 28, 2026 20:27
A pattern fill paints fgColor, but the reader took bgColor. So a solid fill
showed the colour of the pattern background, which is often a different
colour or the legacy slot 64.

The reader now:
- takes a solid fill from fgColor, and no fill from a pattern of none;
- reads a theme colour from the a:clrScheme of the workbook, in the order
  lt1, dk1, lt2, dk2 of a theme index, and moves any colour by its tint;
- reads i, u and strike in a font, and a val of 0 on b;
- reads left and right horizontal alignment, and top and bottom.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NXnz6EZY8YpyiyyE1GpsWy
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NXnz6EZY8YpyiyyE1GpsWy
The workbook found its theme by a target that starts with `theme/`. That
misses a target from the package root, such as `/xl/theme/theme1.xml`.
`parse_relationship_target` matches the relationship type and resolves
both kinds of target.

The test of the alignment now also reads vertical `top` and `bottom`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tigcf9he3w1aHfNPJoEGsd
@andiwand
andiwand force-pushed the fix/xlsx-cell-style-read branch from 2f0eaa3 to 1eb3554 Compare September 28, 2026 18:31
andiwand and others added 2 commits September 28, 2026 20:40
The xlsx theme and the pptx colour scheme read a slot the same way, so
`read_drawing_rgb_color` in `ooxml_util` now does it for both.
`apply_tint` moves next to it, because a docx or pptx colour transform
can use it too. The changelog entry is shorter.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tigcf9he3w1aHfNPJoEGsd
html, pdf and ooxml each had their own copy of the sRGB transfer and of
the conversion from a channel to a byte. The dark fill had Oklab, and
the xlsx tint had HSL. `util/color_util` now holds all of them, and each
module keeps only its own rule on top: `dark_fill`, `apply_tint`, and
the pdf Lab and CMYK spaces.

The formulas do not change, so the reference output stays the same.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tigcf9he3w1aHfNPJoEGsd
@andiwand
andiwand merged commit c026516 into main Sep 28, 2026
50 checks passed
@andiwand
andiwand deleted the fix/xlsx-cell-style-read branch September 28, 2026 18:52
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