Skip to content

Conversation

@dusanradivojevic
Copy link
Contributor

🐛 Problem

SVG <path> elements with multiple subpaths (compound paths with holes) were only rendering correctly when fill-rule="evenodd" was explicitly specified. Paths without a fill-rule attribute (which defaults to nonzero per SVG spec) were rendering as solid shapes instead of showing holes.

Example:
Before:
image
After:
image

🔍 Root Cause

File: src/scene/graphics/shared/svg/SVGParser.ts:150

// BEFORE (buggy)
const hasExplicitEvenodd = fillRule === 'evenodd';
const shouldProcessHoles = hasExplicitEvenodd && hasMultipleSubpaths;

Only processed holes when fill-rule="evenodd" was explicitly set, ignoring the SVG default behavior.

✅ Solution

Changed hole processing logic to handle multi-subpath SVGs regardless of explicit fill-rule attribute:

// AFTER (fixed)
const shouldProcessHoles = hasMultipleSubpaths && fillRule !== 'nonzero';

Logic:

const shouldProcessHoles = hasMultipleSubpaths && fillRule !== 'nonzero';
fill-rule value SVG Spec Default PixiJS Behavior Why
(no attribute) nonzero Process holes via containment Most icon SVGs expect holes to work
"evenodd" N/A Process holes via containment Explicit evenodd intent
"nonzero" N/A Skip hole processing Explicit nonzero = same-winding paths

Since PixiJS uses containment-based hole detection, NOT true nonzero winding direction or evenodd crossing count. This works correctly for most real-world SVGs but isn't fully spec-compliant.

🧪 Tests

Added visual regression tests with social media icon SVGs:

  • svg-icon-google.scene.ts - Single path validation
  • svg-icon-twitter-x.scene.ts - Single path validation
  • svg-icon-discord.scene.ts - Single path validation
  • svg-icon-instagram.scene.ts - Multi-path with holes (validates fix)
  • svg-icons-comparison.scene.ts - Grid comparison

All existing svg-fill-rule-* tests still pass ✅

📊 Impact

SVG Type Before After
Multi-path, no fill-rule ❌ Solid ✅ Holes
Multi-path, fill-rule="evenodd" ✅ Holes ✅ Holes
Multi-path, fill-rule="nonzero" ✅ Solid ✅ Solid
Single path ✅ Works ✅ Works

No breaking changes - all existing functionality preserved.

✨ Result

Icon SVGs (Instagram, social media icons, etc.) now render correctly without requiring manual fill-rule attributes.

  • Tests and/or benchmarks are included
  • Documentation is changed or added
  • Lint process passed (npm run lint)
  • Tests passed (npm run test)

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 22, 2025

pixi.js-basepixi.js-bunny-mark

npm i https://pkg.pr.new/pixijs/pixijs/pixi.js@11727

commit: 683446e

@dusanradivojevic
Copy link
Contributor Author

Hey @Zyie , I think I am having same test running issue like on #11665 can you please assist me with instructions on how to run tests and get OS-agnostic results?

@Zyie
Copy link
Member

Zyie commented Nov 10, 2025

Hey @dusanradivojevic the visual tests are failing because a few svg tests are now broken:

svg.scene.ts
svg-scene-ts-webgl2

graident-bug-svg.scene.ts
gradient-bug-svg-scene-ts-webgl2

It should be only text visual tests that are broken between OS

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.

2 participants