[PATCH] freetype: RFC knockout blending implementation
sarah-kamall <[email protected]> Fri, 26 Dec 2025 15:44:43 +0200
| Newsgroups | gmane.comp.video.videolan.vlc.devel |
|---|---|
| Message-ID | <[email protected]> |
This patch implements knockout blending logic for Freetype renderer. RFC: Should this new knockout blending mode replace the regular mode (as implemented in this patch) or be introduced as a new style flag? Note: This implementation introduces new warnings. Fixes: #29195 Signed-off-by: sarah soliman <[email protected]> --- modules/text_renderer/freetype/blend/blend.h | 20 +++++++++++++++ modules/text_renderer/freetype/blend/rgb.h | 20 +++++++++++++++ modules/text_renderer/freetype/blend/yuv.h | 27 +++++++++++++++++--- modules/text_renderer/freetype/freetype.c | 10 ++++---- 4 files changed, 68 insertions(+), 9 deletions(-) diff --git a/modules/text_renderer/freetype/blend/blend.h b/modules/text_renderer/freetype/blend/blend.h index dd5a39c7e1..8316392370 100644 --- a/modules/text_renderer/freetype/blend/blend.h +++ b/modules/text_renderer/freetype/blend/blend.h @@ -63,6 +63,26 @@ static inline void Blend##name##Pixel( uint8_t **dst, int a, int x, int y, int z }\ } +#define DECL_PIXEL_BLENDER_KNOCKOUT( name, APOS, XPOS, YPOS, ZPOS, APLANE, XPLANE, YPLANE, ZPLANE ) \ +static inline void Blend##name##PixelKnockout( uint8_t **dst, int a, int x, int y, int z, int glyph_a )\ +{\ + if( glyph_a == 0 )\ + return;\ +\ + int i_ao = dst[APLANE][APOS];\ + /* Knockout Mode: Interpolate between Source and Dest based on glyph shape */ \ + /* Result = (Dest * (255 - Glyph) + Src * Glyph) / 255 */ \ + int i_an = (i_ao * (255 - glyph_a) + a * glyph_a) / 255; \ + dst[APLANE][APOS] = i_an; \ +\ + if (i_an > 0)\ + {\ + dst[XPLANE][XPOS] = ( dst[XPLANE][XPOS] * (255 - glyph_a) + x * glyph_a ) / 255;\ + dst[YPLANE][YPOS] = ( dst[YPLANE][YPOS] * (255 - glyph_a) + y * glyph_a ) / 255;\ + dst[ZPLANE][ZPOS] = ( dst[ZPLANE][ZPOS] * (255 - glyph_a) + z * glyph_a ) / 255;\ + }\ +} + static void BlendAXYZLine( picture_t *p_picture, int i_picture_x, int i_picture_y, int i_a, int i_x, int i_y, int i_z, diff --git a/modules/text_renderer/freetype/blend/rgb.h b/modules/text_renderer/freetype/blend/rgb.h index e9490cccab..7e6e1bbfb3 100644 --- a/modules/text_renderer/freetype/blend/rgb.h +++ b/modules/text_renderer/freetype/blend/rgb.h @@ -57,9 +57,11 @@ static void Fill##name##Picture( picture_t *p_picture,\ DECL_RGB_FILLER( RGBA, 3, 0, 1, 2 ); DECL_PIXEL_BLENDER(RGBA, 3, 0, 1, 2, 0, 0, 0, 0); +DECL_PIXEL_BLENDER_KNOCKOUT(RGBA, 3, 0, 1, 2, 0, 0, 0, 0); DECL_RGB_FILLER( ARGB, 0, 1, 2, 3 ); DECL_PIXEL_BLENDER(ARGB, 0, 1, 2, 3, 0, 0, 0, 0); +DECL_PIXEL_BLENDER_KNOCKOUT(ARGB, 0, 1, 2, 3, 0, 0, 0, 0); #undef DECL_RGB_FILLER @@ -107,3 +109,21 @@ static void BlendGlyphToARGB( picture_t *p_picture, i_a, i_x, i_y, i_z, p_glyph, BlendARGBPixel ); } +static void BlendGlyphToRGBAKnockout( picture_t *p_picture, + int i_picture_x, int i_picture_y, + int i_a, int i_x, int i_y, int i_z, + FT_BitmapGlyph p_glyph ) +{ + BlendGlyphToRGB( p_picture, i_picture_x, i_picture_y, + i_a, i_x, i_y, i_z, p_glyph, + BlendRGBAPixelKnockout ); +} +static void BlendGlyphToARGBKnockout( picture_t *p_picture, + int i_picture_x, int i_picture_y, + int i_a, int i_x, int i_y, int i_z, + FT_BitmapGlyph p_glyph ) +{ + BlendGlyphToRGB( p_picture, i_picture_x, i_picture_y, + i_a, i_x, i_y, i_z, p_glyph, + BlendARGBPixelKnockout ); +} diff --git a/modules/text_renderer/freetype/blend/yuv.h b/modules/text_renderer/freetype/blend/yuv.h index d6955a1448..4b6457c6eb 100644 --- a/modules/text_renderer/freetype/blend/yuv.h +++ b/modules/text_renderer/freetype/blend/yuv.h @@ -60,11 +60,13 @@ static void FillYUVAPicture( picture_t *p_picture, } DECL_PIXEL_BLENDER(YUVA, 0, 0, 0, 0, A_PLANE, Y_PLANE, U_PLANE, V_PLANE); +DECL_PIXEL_BLENDER_KNOCKOUT(YUVA, 0, 0, 0, 0, A_PLANE, Y_PLANE, U_PLANE, V_PLANE); -static void BlendGlyphToYUVA( picture_t *p_picture, - int i_picture_x, int i_picture_y, - int i_a, int i_x, int i_y, int i_z, - FT_BitmapGlyph p_glyph ) +static void BlendGlyphToYUVACommon( picture_t *p_picture, + int i_picture_x, int i_picture_y, + int i_a, int i_x, int i_y, int i_z, + FT_BitmapGlyph p_glyph, + void (*BlendPixel)( uint8_t **, int, int, int, int, int ) ) { const uint8_t *srcrow = p_glyph->bitmap.buffer; int i_pitch_src = p_glyph->bitmap.pitch; @@ -101,3 +103,20 @@ static void BlendGlyphToYUVA( picture_t *p_picture, dstrows[3] += p_picture->p[3].i_pitch; } } + +static void BlendGlyphToYUVA( picture_t *p_picture, + int i_picture_x, int i_picture_y, + int i_a, int i_x, int i_y, int i_z, + FT_BitmapGlyph p_glyph ) +{ + BlendGlyphToYUVACommon( p_picture, i_picture_x, i_picture_y, i_a, i_x, i_y, i_z, p_glyph, BlendYUVAPixel ); +} + +static void BlendGlyphToYUVAKnockout( picture_t *p_picture, + int i_picture_x, int i_picture_y, + int i_a, int i_x, int i_y, int i_z, + FT_BitmapGlyph p_glyph ) +{ + BlendGlyphToYUVACommon( p_picture, i_picture_x, i_picture_y, i_a, i_x, i_y, i_z, p_glyph, BlendYUVAPixelKnockout ); +} + diff --git a/modules/text_renderer/freetype/freetype.c b/modules/text_renderer/freetype/freetype.c index 8b49ec7aee..9b4d1d3657 100644 --- a/modules/text_renderer/freetype/freetype.c +++ b/modules/text_renderer/freetype/freetype.c @@ -562,7 +562,7 @@ static void RenderCharAXYZ( filter_t *p_filter, i_color = ch->p_style->i_shadow_color; break; case 1: - i_a = i_a * ch->p_style->i_outline_alpha / 255; + i_a = ch->p_style->i_outline_alpha; i_color = ch->p_style->i_outline_color; break; default: @@ -583,7 +583,7 @@ static void RenderCharAXYZ( filter_t *p_filter, } /* Don't render if invisible or not wanted */ - if( i_a == STYLE_ALPHA_TRANSPARENT || + if( (g == 0 && 0 == (ch->p_style->i_style_flags & STYLE_SHADOW) ) || (g == 1 && 0 == (ch->p_style->i_style_flags & STYLE_OUTLINE) ) ) @@ -1103,7 +1103,7 @@ static subpicture_region_t *Render( filter_t *p_filter, static const ft_drawing_functions DRAW_YUVA = { .extract = YUVFromXRGB, .fill = FillYUVAPicture, - .blend = BlendGlyphToYUVA }; + .blend = BlendGlyphToYUVAKnockout}; func = &DRAW_YUVA; } else if( *p_chroma == VLC_CODEC_RGBA @@ -1112,7 +1112,7 @@ static subpicture_region_t *Render( filter_t *p_filter, static const ft_drawing_functions DRAW_RGBA = { .extract = RGBFromXRGB, .fill = FillRGBAPicture, - .blend = BlendGlyphToRGBA }; + .blend = BlendGlyphToRGBAKnockout }; func = &DRAW_RGBA; } else if( *p_chroma == VLC_CODEC_ARGB @@ -1121,7 +1121,7 @@ static subpicture_region_t *Render( filter_t *p_filter, static const ft_drawing_functions DRAW_ARGB = { .extract = RGBFromXRGB, .fill = FillARGBPicture, - .blend = BlendGlyphToARGB }; + .blend = BlendGlyphToARGBKnockout }; func = &DRAW_ARGB; } else -- 2.43.0 _______________________________________________ vlc-devel mailing list To unsubscribe or modify your subscription options: https://mailman.videolan.org/listinfo/vlc-devel