Skip to content

PDF stage 4.10: tiling patterns (PatternType 1)#574

Merged
andiwand merged 3 commits into
mainfrom
pdf-stage-4.10
Jun 28, 2026
Merged

PDF stage 4.10: tiling patterns (PatternType 1)#574
andiwand merged 3 commits into
mainfrom
pdf-stage-4.10

Conversation

@andiwand

@andiwand andiwand commented Jun 28, 2026

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Stage 4.10 of the PDF→HTML pipeline: render /PatternType 1 tiling patterns selected by scn in a /Pattern colour space, reusing the form-XObject content-stream machinery. Stacked on #573 (4.9); targets pdf-stage-4.9.

What

  • Parserparse_pattern reads a tiling pattern's stream content, /Resources, /BBox, /XStep//YStep and /PaintType. Patterns are now memoized by reference (mirroring XObjects), so a cycle through a tiling pattern's own /Resources resolves to the existing element instead of recursing forever.
  • Extractorpaint_path resolves a tiling pattern to PathElement::fill_pattern plus the pattern /Matrix. scn now keeps the leading colour components for an uncoloured pattern (/PaintType 2), so its underlying fill colour is available to the renderer.
  • HTML — a PatternRegistry runs the tile content as a mini page (extract_page) and emits an SVG <pattern> repeating it every /XStep//YStep, with patternTransform (the pattern /Matrix → page box) placing the lattice; the fill references it as fill="url(#…)". Uncoloured cells are painted in the path's fill colour (folded into the cache key). Only paths and images inside a tile are rendered — nested text/shadings/patterns are skipped (rare).

Tests

  • PdfPageExtractor: a tiling pattern fills a path (fill_pattern + matrix resolved, fill_shading null), and an uncoloured pattern (/PaintType 2) carries its paint colour.

All 199 PDF tests pass; full suite green.

Notes

  • Reference-output submodules are intentionally not bumped here (left for regeneration by the maintainer).
  • Mesh/function shadings (types 1, 4–7) remain a future stage.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6af61917b6

ℹ️ 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".

Comment thread src/odr/internal/pdf/pdf_page_extractor.cpp
Comment thread src/odr/internal/html/pdf_file.cpp
@andiwand andiwand force-pushed the pdf-stage-4.9 branch 2 times, most recently from 89d2a36 to 8384b7b Compare June 28, 2026 15:24
Base automatically changed from pdf-stage-4.9 to main June 28, 2026 16:10
Render `/PatternType 1` tiling patterns selected by `scn` in a `/Pattern`
colour space, reusing the form-XObject content-stream machinery.

- Parser: `parse_pattern` reads a tiling pattern's stream content,
  `/Resources`, `/BBox`, `/XStep`/`/YStep` and `/PaintType`. Patterns are
  memoized by reference (like XObjects) so a cycle through a tiling pattern's
  own `/Resources` resolves to the existing element instead of recursing.
- Extractor: `paint_path` resolves a tiling pattern to
  `PathElement::fill_pattern` + the pattern `/Matrix`. `scn` now keeps the
  leading colour components for an uncoloured pattern (`/PaintType 2`), so its
  underlying fill colour is available.
- HTML: a `PatternRegistry` runs the tile content as a mini page
  (`extract_page`) and emits an SVG `<pattern>` repeating it every
  `/XStep`/`/YStep`, with `patternTransform` placing the lattice; the fill
  references it as `fill="url(#…)"`. Uncoloured cells are painted in the path's
  fill colour (folded into the cache key). Only paths and images inside a tile
  are rendered; nested text/shadings/patterns are skipped.

Tests: a tiling pattern fills a path (`fill_pattern` + matrix), and an
uncoloured pattern carries its paint colour.

Reference-output submodules intentionally not bumped (left for regeneration).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@andiwand andiwand enabled auto-merge (squash) June 28, 2026 17:36
@andiwand andiwand merged commit 500327d into main Jun 28, 2026
11 checks passed
@andiwand andiwand deleted the pdf-stage-4.10 branch June 28, 2026 18:02
andiwand added a commit that referenced this pull request Jun 28, 2026
…up (#575)

Follow-ups on the stage-4.10 tiling-pattern work (#574):

- Fix uncoloured-pattern colour resolution: `ColorSpaceDef::to_rgb` now
  defers `ColorSpaceKind::pattern` to its underlying base, so a `/PaintType 2`
  pattern selected through a named Pattern space (`[/Pattern /DeviceRGB]`)
  paints in its tint instead of black. Adds a regression test.
- Clip each tiling-pattern cell to its `/BBox` so marks outside the cell, or
  in the gap when a step exceeds the BBox, don't leak into the tile.
- Deduplicate the per-page `<defs>` registries (clip/gradient/pattern) behind
  a shared `DefsRegistry` base, and extract an `svg_matrix` helper for the
  repeated `matrix(...)` serialization.
- Use `has_value` for the pattern `/Resources` lookup, matching `/BBox`.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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