@@ -290,6 +290,32 @@ def _check_is_iterable_of_str(infos, key):
290290 f'iterable of str, not { type (infos )} .' )
291291
292292
293+ def _svg_blend_mode (mpl_blend_mode ):
294+ supported_blend_modes = {
295+ "over" : "normal" ,
296+ "multiply" : "multiply" ,
297+ "screen" : "screen" ,
298+ "overlay" : "overlay" ,
299+ "darken" : "darken" ,
300+ "lighten" : "lighten" ,
301+ "color dodge" : "color-dodge" ,
302+ "color burn" : "color-burn" ,
303+ "hard light" : "hard-light" ,
304+ "soft light" : "soft-light" ,
305+ "difference" : "difference" ,
306+ "exclusion" : "exclusion" ,
307+ "hue" : "hue" ,
308+ "saturation" : "saturation" ,
309+ "color" : "color" ,
310+ "luminosity" : "luminosity" ,
311+ }
312+ if mpl_blend_mode in supported_blend_modes :
313+ return supported_blend_modes [mpl_blend_mode ]
314+ _log .warning (f"The '{ mpl_blend_mode } ' blend mode is not supported by the SVG "
315+ f"backend. Falling back to the 'over' blend mode." )
316+ return "normal"
317+
318+
293319class RendererSVG (RendererBase ):
294320 def __init__ (self , width , height , svgwriter , basename = None , image_dpi = 72 ,
295321 * , metadata = None ):
@@ -581,6 +607,8 @@ def _get_style_dict(self, gc, rgbFace):
581607
582608 if forced_alpha and gc .get_alpha () != 1.0 :
583609 attrib ['opacity' ] = _short_float_fmt (gc .get_alpha ())
610+ if (blend_mode := _svg_blend_mode (gc .get_blend_mode ())) != "normal" :
611+ attrib ["mix-blend-mode" ] = blend_mode
584612
585613 offset , seq = gc .get_dashes ()
586614 if seq is not None :
@@ -950,6 +978,8 @@ def draw_image(self, gc, x, y, im, transform=None):
950978 return
951979
952980 clip_attrs = self ._get_clip_attrs (gc )
981+ if (blend_mode := _svg_blend_mode (gc .get_blend_mode ())) != "normal" :
982+ clip_attrs ["style" ] = f"mix-blend-mode: { blend_mode } "
953983 if clip_attrs :
954984 # Can't apply clip-path directly to the image because the image has
955985 # a transformation, which would also be applied to the clip-path.
@@ -1274,6 +1304,8 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
12741304 # docstring inherited
12751305
12761306 clip_attrs = self ._get_clip_attrs (gc )
1307+ if (blend_mode := _svg_blend_mode (gc .get_blend_mode ())) != "normal" :
1308+ clip_attrs ["style" ] = f"mix-blend-mode: { blend_mode } "
12771309 if clip_attrs :
12781310 # Cannot apply clip-path directly to the text, because
12791311 # it has a transformation
0 commit comments