[Concept,02/23] video: Support drawing filled boxes

Message ID 20250915122905.1217249-3-sjg@u-boot.org
State New
Headers
Series expo: Support interactions with a mouse or touchpad |

Commit Message

Simon Glass Sept. 15, 2025, 12:28 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

At present only an outline boxes is supported, albeit with a thickness
parameter. Provide a way to draw a filled rectangle.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 boot/scene.c                 |  2 +-
 drivers/video/video-uclass.c | 27 +++++++++++++++++----------
 include/video.h              |  3 ++-
 test/dm/video.c              | 17 +++++++++++++----
 4 files changed, 33 insertions(+), 16 deletions(-)
  

Patch

diff --git a/boot/scene.c b/boot/scene.c
index 5d2d6617491..564037b0e1a 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -681,7 +681,7 @@  static int scene_obj_render(struct scene_obj *obj, bool text_mode)
 		struct scene_obj_box *box = (struct scene_obj_box *)obj;
 
 		video_draw_box(dev, obj->bbox.x0, obj->bbox.y0, obj->bbox.x1,
-			       obj->bbox.y1, box->width, vid_priv->colour_fg);
+			       obj->bbox.y1, box->width, vid_priv->colour_fg, false);
 		break;
 	}
 	case SCENEOBJT_TEXTEDIT: {
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index c02fd9bb958..324817aa5ce 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -218,7 +218,7 @@  int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
 }
 
 int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1,
-		   int width, u32 colour)
+		   int width, u32 colour, bool fill)
 {
 	struct video_priv *priv = dev_get_uclass_priv(dev);
 	int pbytes = VNBYTES(priv->bpix);
@@ -233,17 +233,24 @@  int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1,
 		void *ptr = line;
 		int i;
 
-		for (i = 0; i < width; i++)
-			fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
-		if (row < y0 + width || row >= y1 - width) {
-			for (i = 0; i < pixels - width * 2; i++)
-				fill_pixel_and_goto_next(&ptr, colour, pbytes,
-							 pbytes);
+		if (fill) {
+			/* fill the entire row */
+			for (i = 0; i < pixels; i++)
+				fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
 		} else {
-			ptr += (pixels - width * 2) * pbytes;
+			/* draw outline only */
+			for (i = 0; i < width; i++)
+				fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
+			if (row < y0 + width || row >= y1 - width) {
+				for (i = 0; i < pixels - width * 2; i++)
+					fill_pixel_and_goto_next(&ptr, colour, pbytes,
+								 pbytes);
+			} else {
+				ptr += (pixels - width * 2) * pbytes;
+			}
+			for (i = 0; i < width; i++)
+				fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
 		}
-		for (i = 0; i < width; i++)
-			fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
 		line += priv->line_length;
 	}
 	video_damage(dev, x0, y0, x1 - x0, y1 - y0);
diff --git a/include/video.h b/include/video.h
index b2eaecf5866..9f891cf9d30 100644
--- a/include/video.h
+++ b/include/video.h
@@ -277,10 +277,11 @@  int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
  * @y1:		Y end position in pixels from the top
  * @width:	width in pixels
  * @colour:	Value to write
+ * @fill:	true to fill the box, false to draw outline only
  * Return: 0 if OK, -ENOSYS if the display depth is not supported
  */
 int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1,
-		   int width, u32 colour);
+		   int width, u32 colour, bool fill);
 
 /**
  * video_sync() - Sync a device's frame buffer with its hardware
diff --git a/test/dm/video.c b/test/dm/video.c
index e48f6b078c7..8fc1a4d8b0d 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -911,14 +911,23 @@  static int dm_test_video_box(struct unit_test_state *uts)
 
 	ut_assertok(video_get_nologo(uts, &dev));
 	priv = dev_get_uclass_priv(dev);
+
+	/* test outline boxes */
 	video_draw_box(dev, 100, 100, 200, 200, 3,
-		       video_index_to_colour(priv, VID_LIGHT_BLUE));
+		       video_index_to_colour(priv, VID_LIGHT_BLUE), false);
 	video_draw_box(dev, 300, 100, 400, 200, 1,
-		       video_index_to_colour(priv, VID_MAGENTA));
+		       video_index_to_colour(priv, VID_MAGENTA), false);
 	video_draw_box(dev, 500, 100, 600, 200, 20,
-		       video_index_to_colour(priv, VID_LIGHT_RED));
+		       video_index_to_colour(priv, VID_LIGHT_RED), false);
 	ut_asserteq(133, video_compress_fb(uts, dev, false));
-	ut_assertok(video_check_copy_fb(uts, dev));
+	
+	/* test filled boxes */
+	video_draw_box(dev, 150, 250, 200, 300, 0,
+		       video_index_to_colour(priv, VID_GREEN), true);
+	video_draw_box(dev, 350, 250, 400, 300, 0,
+		       video_index_to_colour(priv, VID_YELLOW), true);
+
+	ut_asserteq(175, video_compress_fb(uts, dev, false));
 
 	return 0;
 }