fb: cfb: Add cfb_draw_line() API

Add cfb_draw_line() API for rendering line.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
diff --git a/include/zephyr/display/cfb.h b/include/zephyr/display/cfb.h
index e7dc53b..fde4e16 100644
--- a/include/zephyr/display/cfb.h
+++ b/include/zephyr/display/cfb.h
@@ -120,6 +120,18 @@
 int cfb_draw_point(const struct device *dev, const struct cfb_position *pos);
 
 /**
+ * @brief Draw a line.
+ *
+ * @param dev Pointer to device structure for driver instance
+ * @param start start position of the line
+ * @param end end position of the line
+ *
+ * @return 0 on success, negative value otherwise
+ */
+int cfb_draw_line(const struct device *dev, const struct cfb_position *start,
+		  const struct cfb_position *end);
+
+/**
  * @brief Clear framebuffer.
  *
  * @param dev Pointer to device structure for driver instance
diff --git a/subsys/fb/cfb.c b/subsys/fb/cfb.c
index 010151a..a4cdddd 100644
--- a/subsys/fb/cfb.c
+++ b/subsys/fb/cfb.c
@@ -204,6 +204,36 @@
 	fb->buf[index + x] |= m;
 }
 
+static void draw_line(struct char_framebuffer *fb, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
+{
+	int16_t sx = (x0 < x1) ? 1 : -1;
+	int16_t sy = (y0 < y1) ? 1 : -1;
+	int16_t dx = (sx > 0) ? (x1 - x0) : (x0 - x1);
+	int16_t dy = (sy > 0) ? (y0 - y1) : (y1 - y0);
+	int16_t err = dx + dy;
+	int16_t e2;
+
+	while (true) {
+		draw_point(fb, x0, y0);
+
+		if (x0 == x1 && y0 == y1) {
+			break;
+		}
+
+		e2 = 2 * err;
+
+		if (e2 >= dy) {
+			err += dy;
+			x0 += sx;
+		}
+
+		if (e2 <= dx) {
+			err += dx;
+			y0 += sy;
+		}
+	}
+}
+
 static int draw_text(const struct device *dev, const char *const str, int16_t x, int16_t y,
 		     bool wrap)
 {
@@ -245,6 +275,16 @@
 	return 0;
 }
 
+int cfb_draw_line(const struct device *dev, const struct cfb_position *start,
+		  const struct cfb_position *end)
+{
+	struct char_framebuffer *fb = &char_fb;
+
+	draw_line(fb, start->x, start->y, end->x, end->y);
+
+	return 0;
+}
+
 int cfb_draw_text(const struct device *dev, const char *const str, int16_t x, int16_t y)
 {
 	return draw_text(dev, str, x, y, false);