code wiki / (root) / nx_paint_text_test.nx

nx_paint_text_test.nx source

↩ module page · 130 lines · 4869 B

1// nx_paint_text_test.nx -- smoke for the 5x7 text rasterizer. 2// Paints "42" into a 32x16 framebuffer and verifies per-pixel 3// rendering against the known glyph bit patterns. 4 5import "nx_syscalls.nx" 6import "nx_css_color_decode.nx" 7import "nx_paint_solid_rect.nx" 8import "nx_font_bitmap_5x7.nx" 9import "nx_paint_text.nx" 10 11func _put_byte(buf: *u8, i: i64, v: i64) -> i64 { 12 buf[i] = v as u8 13 return 0 14} 15 16func main() -> i64 { 17 let w: i64 = 32 18 let h: i64 = 16 19 let pixels: *u8 = (sys_mmap((w * h * 4) as nx_size)) as *u8 20 let fb: *Framebuffer = (sys_mmap(NX_FRAMEBUFFER_BYTES as nx_size)) as *Framebuffer 21 nx_framebuffer_init(fb, pixels, w, h) 22 nx_framebuffer_clear(fb) 23 24 let red: *CssColor = (sys_mmap(NX_CSS_COLOR_BYTES as nx_size)) as *CssColor 25 red.r = 255 26 red.g = 0 27 red.b = 0 28 red.a = 255 29 30 // text = "42" (chars 52 and 50) 31 let text: *u8 = (sys_mmap(8)) as *u8 32 _put_byte(text, 0, 52) // '4' 33 _put_byte(text, 1, 50) // '2' 34 35 // Paint at (3, 2). Cell stride 6, so '4' covers (3..7, 2..8) and 36 // '2' covers (9..13, 2..8). 37 let pixels_set: i64 = nx_paint_text(fb, 3, 2, text, 2, red) 38 39 // '4' glyph (rows 0..6): 40 // row 0: ...#. -> col 3 set in cell -> px (6, 2) 41 // row 1: ..##. -> cols 2,3 -> (5, 3), (6, 3) 42 // row 2: .#.#. -> cols 1, 3 -> (4, 4), (6, 4) 43 // row 3: #..#. -> cols 0, 3 -> (3, 5), (6, 5) 44 // row 4: ##### -> cols 0..4 -> (3, 6), (4, 6), (5, 6), (6, 6), (7, 6) 45 // row 5: ...#. -> col 3 -> (6, 7) 46 // row 6: ...#. -> col 3 -> (6, 8) 47 // Total '4' lit pixels: 1+2+2+2+5+1+1 = 14 48 // 49 // '2' glyph (rows 0..6): 50 // row 0: .###. -> cols 1,2,3 -> (10, 2), (11, 2), (12, 2) 51 // row 1: #...# -> cols 0, 4 -> (9, 3), (13, 3) 52 // row 2: ....# -> col 4 -> (13, 4) 53 // row 3: ...#. -> col 3 -> (12, 5) 54 // row 4: ..#.. -> col 2 -> (11, 6) 55 // row 5: .#... -> col 1 -> (10, 7) 56 // row 6: ##### -> cols 0..4 -> (9, 8), (10, 8), (11, 8), (12, 8), (13, 8) 57 // Total '2' lit pixels: 3+2+1+1+1+1+5 = 14 58 // 59 // Grand total = 28. 60 if pixels_set != 28 { return 1 } 61 62 let probe: *CssColor = (sys_mmap(NX_CSS_COLOR_BYTES as nx_size)) as *CssColor 63 64 // Spot-check '4' row 4 (horizontal bar): pixels (3..7, 6) all red. 65 nx_framebuffer_get_pixel(fb, 3, 6, probe) 66 if probe.r != 255 { return 10 } 67 nx_framebuffer_get_pixel(fb, 7, 6, probe) 68 if probe.r != 255 { return 11 } 69 70 // '4' row 6 (descender stub): only (6, 8) lit; (5, 8) not lit. 71 nx_framebuffer_get_pixel(fb, 6, 8, probe) 72 if probe.r != 255 { return 12 } 73 nx_framebuffer_get_pixel(fb, 5, 8, probe) 74 if probe.r != 0 { return 13 } 75 76 // '2' row 0: (10, 2) lit, (9, 2) not lit (leftmost col 0 = bit 4 = 0). 77 nx_framebuffer_get_pixel(fb, 10, 2, probe) 78 if probe.r != 255 { return 20 } 79 nx_framebuffer_get_pixel(fb, 9, 2, probe) 80 if probe.r != 0 { return 21 } 81 82 // '2' row 6 (bottom bar): all 5 pixels (9..13, 8) lit. 83 nx_framebuffer_get_pixel(fb, 9, 8, probe) 84 if probe.r != 255 { return 30 } 85 nx_framebuffer_get_pixel(fb, 13, 8, probe) 86 if probe.r != 255 { return 31 } 87 88 // Inter-char gap: column 8 at any row should be clear (between 89 // glyph cells). 90 nx_framebuffer_get_pixel(fb, 8, 6, probe) 91 if probe.r != 0 { return 40 } 92 93 // Above text region: clear. 94 nx_framebuffer_get_pixel(fb, 5, 0, probe) 95 if probe.r != 0 { return 50 } 96 // Below text region (row > 8): clear. 97 nx_framebuffer_get_pixel(fb, 5, 10, probe) 98 if probe.r != 0 { return 51 } 99 100 // ---- Measure helper ---- 101 if nx_paint_text_measure(0) != 0 { return 60 } 102 if nx_paint_text_measure(1) != 6 { return 61 } 103 if nx_paint_text_measure(5) != 30 { return 62 } 104 if nx_paint_text_measure(0 - 1) != 0 { return 63 } 105 106 // ---- Unsupported chars consume cell width but emit zero pixels ---- 107 nx_framebuffer_clear(fb) 108 let unsup: *u8 = (sys_mmap(4)) as *u8 109 _put_byte(unsup, 0, 64) // '@' (unsupported -- 'A' is now a real glyph) 110 let n_unsup: i64 = nx_paint_text(fb, 0, 0, unsup, 1, red) 111 if n_unsup != 0 { return 70 } 112 // Confirm framebuffer is still all zero. 113 nx_framebuffer_get_pixel(fb, 2, 3, probe) 114 if probe.r != 0 { return 71 } 115 116 // ---- Transparent foreground (alpha=0) emits zero pixels ---- 117 let invisible: *CssColor = (sys_mmap(NX_CSS_COLOR_BYTES as nx_size)) as *CssColor 118 invisible.r = 255 119 invisible.g = 255 120 invisible.b = 255 121 invisible.a = 0 122 nx_framebuffer_clear(fb) 123 if nx_paint_text(fb, 0, 0, text, 2, invisible) != 0 { return 80 } 124 125 // ---- Empty / negative text_len is no-op ---- 126 if nx_paint_text(fb, 0, 0, text, 0, red) != 0 { return 90 } 127 if nx_paint_text(fb, 0, 0, text, 0 - 1, red) != 0 { return 91 } 128 129 return 0 130}