Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing Blend Modes and expose BlendMode on Image Control #17903

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

leocb
Copy link

@leocb leocb commented Jan 7, 2025

What does the pull request do?

This PR adds a few missing Blend Modes to the Avalonia blend modes Enum, which enables them to be used in the context render options directly.
This PR also exposes the Blend Mode render option in the Image Control as a StyledProperty RenderMode

What is the current behavior?

Currently the only way to access some blend modes is to use Skia API directly on a custom control, this PR greatly simplifies this.

What is the updated/expected behavior with this PR?

Now simply setting the BlendMode property on the Image control draws the image as expected

How was the solution implemented (if it's not obvious)?

I Added a PushRenderOptions in the Render method of the Image Control

Checklist

Fixed issues

Possibly Closes #17901 (if closing discussions from a PR is a thing)

@Gillibald
Copy link
Contributor

Can you add a render test?

https://github.com/AvaloniaUI/Avalonia/blob/master/tests/Avalonia.RenderTests/Controls/ImageTests.cs

@cla-avalonia
Copy link
Collaborator

cla-avalonia commented Jan 7, 2025

  • All contributors have signed the CLA.

@leocb
Copy link
Author

leocb commented Jan 7, 2025

@cla-avalonia agree

@robloo
Copy link
Contributor

robloo commented Jan 7, 2025

Isn't this overconstrained to the Skia backend now? We really shouldn't design for Skia by itself. That's caused problems other places already.

IMO this should be abstracted rather than passed through.

@Gillibald
Copy link
Contributor

Direct2D version for reference: https://learn.microsoft.com/en-us/windows/win32/direct2d/blend#blend-modes

@leocb
Copy link
Author

leocb commented Jan 7, 2025

I'll see what I can do about D2D, since I used avalonia's Enum for setting the image blend mode, should be straight forward to enable it in D2D too, maybe.

On another note, I see some tests failing, Is the way I did the options push correct? I tried other methods and none worked, I also don't see what I did anywhere else in the code, which worries me I'm doing something not the intended way.

Please advise

Fix image blendMode change not triggering a re-render
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.3.999-cibuild0054137-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@leocb
Copy link
Author

leocb commented Jan 7, 2025

// TODO: How to implement CompositeMode here?

Composite mode is required to use Blend Modes in D2D, implementing this would fall out of what I'm capable of, I think. I'll try tomorrow but no promises. Any pointers would be helpful.

@Gillibald
Copy link
Contributor

Gillibald commented Jan 8, 2025

Just make sure Avalonia's blend modes are covering options that are supported by major drawing libraries. Don't just map Skia 1:1

You do not have to implement the D2D part

@leocb
Copy link
Author

leocb commented Jan 8, 2025

Well, I believe that what I added to the Avalonia Enum are the blend modes basically everybody supports, a few modifications I'd want to do:

  • Remove:
    • Modulate: same as Multiply, but the only one that also affects alpha channel.
    • Destination: which, by definition, does nothing, so why have it in the first place.
  • Add:
    • Subtract: Dest color - Source color
    • Division: Dest color / Source color

I'd also consider separating them into 2 enums, composition (alpha operations) and blend (pre alpha-mult color operations) - Skia bundles them all together, but D2D has them separate

However, separating them would be a breaking change, your call.

Here's how the current enums map to each other:
Question: would the modes that are not supported simply render as the default?

Composite modes:

Avalonia: Skia D2D Photoshop
Unspecified kSrcOver D2D1_COMPOSITE_MODE_SOURCE_OVER Normal
SourceOver kSrcOver D2D1_COMPOSITE_MODE_SOURCE_OVER Normal
Source kSrc D2D1_COMPOSITE_MODE_SOURCE_COPY
Destination ❌ kDst
DestinationOver kDstOver D2D1_COMPOSITE_MODE_DESTINATION_OVER
SourceIn kSrcIn D2D1_COMPOSITE_MODE_SOURCE_IN
DestinationIn kDstIn D2D1_COMPOSITE_MODE_DESTINATION_IN
SourceOut kSrcOut D2D1_COMPOSITE_MODE_SOURCE_OUT
DestinationOut kDstOut D2D1_COMPOSITE_MODE_DESTINATION_OUT
SourceAtop kSrcATop D2D1_COMPOSITE_MODE_SOURCE_ATOP
DestinationAtop kDstATop D2D1_COMPOSITE_MODE_DESTINATION_ATOP
Xor kXor D2D1_COMPOSITE_MODE_XOR
kClear Clear
D2D1_COMPOSITE_MODE_BOUNDED_SOURCE_COPY
D2D1_COMPOSITE_MODE_MASK_INVERT

Blend Modes

Avalonia: Skia D2D Photoshop
Screen kScreen D2D1_BLEND_MODE_SCREEN Screen
Overlay kOverlay D2D1_BLEND_MODE_OVERLAY Overlay
Plus kPlus D2D1_BLEND_MODE_LINEAR_DODGE Linear Dodge (Add)
Subtract ➕ D2D1_BLEND_MODE_SUBTRACT Subtract
Darken kDarken D2D1_BLEND_MODE_DARKEN Darken
Lighten kLighten D2D1_BLEND_MODE_LIGHTEN Lighten
ColorDodge kColorDodge D2D1_BLEND_MODE_COLOR_DODGE Color Dodge
ColorBurn kColorBurn D2D1_BLEND_MODE_COLOR_BURN Color Burn
HardLight kHardLight D2D1_BLEND_MODE_HARD_LIGHT Hard Light
SoftLight kSoftLight D2D1_BLEND_MODE_SOFT_LIGHT Soft Light
Difference kDifference D2D1_BLEND_MODE_DIFFERENCE Difference
Exclusion kExclusion D2D1_BLEND_MODE_EXCLUSION Exclusion
Division ➕ D2D1_BLEND_MODE_DIVISION Divide
Multiply kMultiply D2D1_BLEND_MODE_MULTIPLY Multiply
Modulate ❌ kModulate
Hue kHue D2D1_BLEND_MODE_HUE Hue
Saturation kSaturation D2D1_BLEND_MODE_SATURATION Saturation
Color kColor D2D1_BLEND_MODE_COLOR Color
Luminosity kLuminosity D2D1_BLEND_MODE_LUMINOSITY Luminosity
D2D1_BLEND_MODE_LINEAR_BURN Linear Burn
D2D1_BLEND_MODE_DARKER_COLOR Darker Color
D2D1_BLEND_MODE_LIGHTER_COLOR Lighter Color
D2D1_BLEND_MODE_VIVID_LIGHT Vivid Light
D2D1_BLEND_MODE_LINEAR_LIGHT Linear Light
D2D1_BLEND_MODE_PIN_LIGHT Pin Light
D2D1_BLEND_MODE_HARD_MIX Hard Mix
D2D1_BLEND_MODE_DISSOLVE Dissolve

These last blend modes are variations of other blend modes, mostly never used

@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.3.999-cibuild0054157-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

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.

5 participants