⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/graphics/
cursor.rs

1//! Hardware cursor sprite rendering.
2//!
3//! Provides a 16x16 arrow cursor bitmap and a compositing function
4//! to overlay the cursor onto the framebuffer back-buffer.
5
6/// Cursor width in pixels.
7pub const CURSOR_WIDTH: usize = 16;
8/// Cursor height in pixels.
9pub const CURSOR_HEIGHT: usize = 16;
10
11/// 16x16 arrow cursor bitmap.
12///
13/// Each row is a u16 where bit 15 = leftmost pixel.
14/// Value 1 = white foreground, 0 = transparent.
15/// A separate mask defines the black outline.
16const CURSOR_DATA: [u16; CURSOR_HEIGHT] = [
17    0b1000_0000_0000_0000, // *
18    0b1100_0000_0000_0000, // **
19    0b1110_0000_0000_0000, // ***
20    0b1111_0000_0000_0000, // ****
21    0b1111_1000_0000_0000, // *****
22    0b1111_1100_0000_0000, // ******
23    0b1111_1110_0000_0000, // *******
24    0b1111_1111_0000_0000, // ********
25    0b1111_1111_1000_0000, // *********
26    0b1111_1100_0000_0000, // ******
27    0b1111_0110_0000_0000, // ** **
28    0b1110_0011_0000_0000, // * **
29    0b1100_0011_0000_0000, //    **
30    0b0000_0001_1000_0000, //     **
31    0b0000_0001_1000_0000, //     **
32    0b0000_0000_0000_0000, //
33];
34
35/// Cursor outline mask (black border for visibility on any background).
36const CURSOR_MASK: [u16; CURSOR_HEIGHT] = [
37    0b1100_0000_0000_0000,
38    0b1110_0000_0000_0000,
39    0b1111_0000_0000_0000,
40    0b1111_1000_0000_0000,
41    0b1111_1100_0000_0000,
42    0b1111_1110_0000_0000,
43    0b1111_1111_0000_0000,
44    0b1111_1111_1000_0000,
45    0b1111_1111_1100_0000,
46    0b1111_1111_1100_0000,
47    0b1111_1111_0000_0000,
48    0b1111_0111_1000_0000,
49    0b1110_0111_1000_0000,
50    0b0000_0011_1100_0000,
51    0b0000_0011_1100_0000,
52    0b0000_0001_1100_0000,
53];
54
55/// Draw the cursor sprite onto a pixel buffer.
56///
57/// # Arguments
58/// - `buf`: Pixel buffer (BGRA format, 4 bytes/pixel).
59/// - `stride`: Buffer stride in bytes.
60/// - `buf_width`: Buffer width in pixels.
61/// - `buf_height`: Buffer height in pixels.
62/// - `cx`, `cy`: Cursor position (top-left of sprite).
63pub fn draw_cursor(
64    buf: &mut [u8],
65    stride: usize,
66    buf_width: usize,
67    buf_height: usize,
68    cx: i32,
69    cy: i32,
70) {
71    for row in 0..CURSOR_HEIGHT {
72        let py = cy as usize + row;
73        if py >= buf_height {
74            break;
75        }
76        let mask_bits = CURSOR_MASK[row];
77        let data_bits = CURSOR_DATA[row];
78
79        for col in 0..CURSOR_WIDTH {
80            let px = cx as usize + col;
81            if px >= buf_width {
82                break;
83            }
84
85            let bit = 15 - col;
86            let in_mask = (mask_bits >> bit) & 1 != 0;
87            let in_data = (data_bits >> bit) & 1 != 0;
88
89            if in_mask {
90                let offset = py * stride + px * 4;
91                if offset + 3 < buf.len() {
92                    if in_data {
93                        // White foreground
94                        buf[offset] = 0xFF;
95                        buf[offset + 1] = 0xFF;
96                        buf[offset + 2] = 0xFF;
97                        buf[offset + 3] = 0xFF;
98                    } else {
99                        // Black outline
100                        buf[offset] = 0x00;
101                        buf[offset + 1] = 0x00;
102                        buf[offset + 2] = 0x00;
103                        buf[offset + 3] = 0xFF;
104                    }
105                }
106            }
107        }
108    }
109}