Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix bug with an isolated blend group in Cairo with certain group blend modes - #32326

Open
ayshih wants to merge 1 commit into
matplotlib:mainfrom
ayshih:cairo_blend_group_porterduff
Open

Fix bug with an isolated blend group in Cairo with certain group blend modes#32326
ayshih wants to merge 1 commit into
matplotlib:mainfrom
ayshih:cairo_blend_group_porterduff

Conversation

@ayshih

@ayshih ayshih commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

PR summary

This PR fixes a bug when using an isolated blend group (see #31162) in Cairo and setting the group blend mode to "knockout" or "clear". These two Porter-Duff compositing operators in Cairo have the behavior that a fully transparent pixel in the isolated buffer will override the underlying backdrop pixel, so the current code ends up erasing the entire backdrop when painting the isolated buffer. This PR uses a mask so that the isolated buffer is not painted where the isolated buffer is fully transparent.

AI Disclosure

No AI was used

PR quality check

  • Use an expressive title, e.g. "Fix title font property precedence"
  • New and changed code is tested
  • [N/A] Plotting related features are demonstrated in an example
  • [N/A] New features and API changes have release notes
  • [N/A] Documentation complies with general and docstring guidelines

@ayshih ayshih added this to the v3.12.0 milestone Sep 9, 2026
@ayshih
ayshih force-pushed the cairo_blend_group_porterduff branch from 1d8ce47 to 5e58ef0 Compare September 9, 2026 15:22
@ayshih
ayshih marked this pull request as ready for review September 9, 2026 15:42
Comment thread lib/matplotlib/backends/backend_cairo.py Outdated
Comment on lines +394 to +395
mask_buf = np.asarray(mask_surface.get_data())
mask_buf[mask_buf > 0] = 255 * group_state.alpha + 0.5

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this equivalent to a fill of the group alpha with operator set to ATOP for the context? Not sure if that's faster or not than accessing with NumPy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

From my understanding, the issue is that Cairo either explicitly treats 0 as a special case or has a bug where 0 "will override the underlying backdrop pixel". This behavior is not part of the Porter-Duff blend mode formulas.

I tried to think of a way to better vectorize this when I was reviewing last night, but was unable to come up with anything. The only idea I had was doing a min() on the whole mask_buf to see if a 0 was present. But that will add work if we are expecting this code to usually run.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's my understanding for the overall operation, but I'm only asking about the modification of mask_surface/mask_ctx.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is this equivalent to a fill of the group alpha with operator set to ATOP for the context? Not sure if that's faster or not than accessing with NumPy.

Conceptually, yes, but I think it'd be likely more confusing to maintainers, plus I'd have to imagine it'd be slower than just using NumPy since Cairo provides direct access to the byte buffer and we don't have to byte unpack or even reshape.

Comment thread lib/matplotlib/backends/backend_cairo.py Outdated
@ayshih
ayshih force-pushed the cairo_blend_group_porterduff branch from 5e58ef0 to 78d3876 Compare September 10, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants