From: Simon Glass <sjg@chromium.org> Provide a new BMP function which can draw a bitmap while regarding a chosen colour as transparent. Signed-off-by: Simon Glass <sjg@chromium.org> --- drivers/video/video_bmp.c | 6 ++++ include/video.h | 16 ++++++++++ test/dm/video.c | 62 ++++++++++++++++++++++++++++++++------- 3 files changed, 74 insertions(+), 10 deletions(-) diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c index ebdf73e25a9..43aa45f0efe 100644 --- a/drivers/video/video_bmp.c +++ b/drivers/video/video_bmp.c @@ -507,3 +507,9 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, { return draw_bmp(dev, bmp_image, x, y, align, false, 0); } + +int video_bmp_displaya(struct udevice *dev, ulong bmp_image, int x, int y, + bool align, bool alpha, u32 acolour) +{ + return draw_bmp(dev, bmp_image, x, y, align, alpha, acolour); +} diff --git a/include/video.h b/include/video.h index 9d9a725d30d..1ad5868e2f6 100644 --- a/include/video.h +++ b/include/video.h @@ -383,6 +383,22 @@ void video_bmp_get_info(const void *bmp_image, ulong *widthp, ulong *heightp, int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, bool align); +/** + * video_bmp_displaya() - Display a BMP image with alpha transparency + * + * @dev: Device to use + * @bmp_image: Address of BMP image + * @x: X position to draw image + * @y: Y position to draw image + * @align: true to adjust the coordinates to centre the image (see + * video_bmp_display() for details) + * @alpha: true to enable alpha transparency + * @acolour: Color to treat as transparent (RGB888 format: 0xRRGGBB) + * Return: 0 if OK, -ve on error + */ +int video_bmp_displaya(struct udevice *dev, ulong bmp_image, int x, int y, + bool align, bool alpha, u32 acolour); + /** * video_get_xsize() - Get the width of the display in pixels * diff --git a/test/dm/video.c b/test/dm/video.c index a802228b790..3defa184b14 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -667,15 +667,25 @@ static int dm_test_video_comp_bmp8(struct unit_test_state *uts) } DM_TEST(dm_test_video_comp_bmp8, UTF_SCAN_PDATA | UTF_SCAN_FDT); -/* Test drawing the riscos pointer */ -static int dm_test_video_bmp_alpha(struct unit_test_state *uts) +/** + * check_bmp_alpha() - Test drawing the riscos pointer with transparency + * + * Draws the riscos pointer BMP in various positions with and without + * transparency to verify alpha blending works correctly + * + * @uts: Test state + * @dev: Video device + * @first: Expected compression after first pointer draw + * @second: Expected compression after second pointer draw + * @trans: Expected compression after drawing with transparency + * Return: 0 if OK, -ve on error + */ +static int check_bmp_alpha(struct unit_test_state *uts, struct udevice *dev, + int first, int second, int trans) { - struct video_priv *priv; - struct udevice *dev; + struct video_priv *priv = dev_get_uclass_priv(dev); ulong addr; - ut_assertok(video_get_nologo(uts, &dev)); - priv = dev_get_uclass_priv(dev); addr = map_to_sysmem(video_image_getptr(riscos_arrow)); /* Draw a black rectangle first */ @@ -684,17 +694,49 @@ static int dm_test_video_bmp_alpha(struct unit_test_state *uts) /* Draw the pointer on top of the black rectangle */ ut_assertok(video_bmp_display(dev, addr, 110, 110, false)); - ut_asserteq(174, video_compress_fb(uts, dev, false)); + ut_asserteq(first, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); - /* Draw the pointer on top of the black rectangle */ + /* Draw the pointer on top of the white background */ ut_assertok(video_bmp_display(dev, addr, 350, 110, false)); - ut_asserteq(249, video_compress_fb(uts, dev, false)); + ut_asserteq(second, video_compress_fb(uts, dev, false)); + + /* Draw the pointer with white (0xffffff) as transparent */ + ut_assertok(video_bmp_displaya(dev, addr, 110, 160, false, true, + 0xffffff)); + ut_assertok(video_bmp_displaya(dev, addr, 350, 160, false, true, + 0xffffff)); + ut_asserteq(trans, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); return 0; } -DM_TEST(dm_test_video_bmp_alpha, UTF_SCAN_PDATA | UTF_SCAN_FDT); + +/* Test drawing the riscos pointer on a 16bpp display */ +static int dm_test_video_bmp_alpha16(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(video_get_nologo(uts, &dev)); + ut_assertok(check_bmp_alpha(uts, dev, 174, 249, 358)); + + return 0; +} +DM_TEST(dm_test_video_bmp_alpha16, UTF_SCAN_PDATA | UTF_SCAN_FDT); + +/* Test drawing the riscos pointer on 32bpp display */ +static int dm_test_video_bmp_alpha32(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_find_first_device(UCLASS_VIDEO, &dev)); + ut_assertnonnull(dev); + ut_assertok(sandbox_sdl_set_bpp(dev, VIDEO_BPP32)); + ut_assertok(check_bmp_alpha(uts, dev, 641, 710, 869)); + + return 0; +} +DM_TEST(dm_test_video_bmp_alpha32, UTF_SCAN_PDATA | UTF_SCAN_FDT); /* Test TrueType console */ static int dm_test_video_truetype(struct unit_test_state *uts) -- 2.43.0