code wiki / _hdl_build / nx_cyrillic_render_gate.nx
nx_cyrillic_render_gate.nx source
↩ module page · 101 lines · 5008 B
1// nx_cyrillic_render_gate.nx -- proves NATIVE Cyrillic + Latin caption rendering, NO fake green. Renders the
2// Russian caption "привет друг" (uppercase-folded -> ПРИВЕТ ДРУГ) and the Latin caption "HELLO FRIEND" onto two
3// video frames; asserts each sets glyph pixels, asserts the bar is drawn, and a neg-control (empty caption sets
4// 0 pixels). Eyeball -> knowledge/nx_cyrillic_render.png (Cyrillic top, Latin bottom). expect_exit: 0 license_tier: ORIGINAL
5import "nx_syscalls.nx"
6import "nx_css_color_decode.nx"
7import "nx_paint_solid_rect.nx"
8import "nx_font8x8.nx"
9import "nx_font_cyrillic8.nx"
10import "nx_utf8.nx"
11import "nx_caption_render_uni.nx"
12import "nx_png_write.nx"
13import "nx_gate_verdict.nx"
14
15func rg(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
16func rgn(v: i64) -> i64 {
17 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
18 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
19 let d: *u8 = sys_mmap(24); var k: i64 = 0
20 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
21 var j: i64 = k - 1
22 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 }
23 return 0
24}
25func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
26func mkfb(w: i64, h: i64) -> *Framebuffer {
27 let px: *u8 = sys_mmap(w * h * 4)
28 let fb: *Framebuffer = sys_mmap(NX_FRAMEBUFFER_BYTES) as *Framebuffer
29 nx_framebuffer_init(fb, px, w, h)
30 nx_framebuffer_clear(fb)
31 return fb
32}
33
34func main() -> i64 {
35 rg("=== nx_cyrillic_render_gate: native Cyrillic + Latin caption rendering ===\n" as *u8)
36 let w: i64 = 320
37 let h: i64 = 90
38 var pass: i64 = 0
39 var fail: i64 = 0
40
41 let vid: *CssColor = sys_mmap(NX_CSS_COLOR_BYTES) as *CssColor
42 vid.r=30; vid.g=44; vid.b=64; vid.a=255
43 let bar: *CssColor = sys_mmap(NX_CSS_COLOR_BYTES) as *CssColor
44 bar.r=0; bar.g=0; bar.b=0; bar.a=255
45 let fg: *CssColor = sys_mmap(NX_CSS_COLOR_BYTES) as *CssColor
46 fg.r=255; fg.g=235; fg.b=60; fg.a=255
47 let probe: *CssColor = sys_mmap(NX_CSS_COLOR_BYTES) as *CssColor
48
49 // CYRILLIC frame
50 let fbC: *Framebuffer = mkfb(w, h)
51 nx_paint_solid_rect(fbC, 0, 0, w, h, vid)
52 let ru: *u8 = "привет друг" as *u8
53 let setC: i64 = nx_caption_render_uni(fbC, ru, slen(ru), 2, bar, fg)
54 rg(" Cyrillic 'привет друг' -> glyph px = " as *u8); rgn(setC); rg("\n" as *u8)
55 if setC > 0 { pass=pass+1; rg(" ROW cyrillic-renders: GREEN\n" as *u8) } else { fail=fail+1; rg(" ROW cyrillic-renders: RED\n" as *u8) }
56 nx_framebuffer_get_pixel(fbC, 3, h-3, probe)
57 if probe.r==0 { if probe.g==0 { if probe.b==0 { pass=pass+1; rg(" ROW bar-drawn: GREEN\n" as *u8) } else { fail=fail+1 } } else { fail=fail+1 } } else { fail=fail+1; rg(" ROW bar-drawn: RED\n" as *u8) }
58
59 // LATIN frame
60 let fbL: *Framebuffer = mkfb(w, h)
61 nx_paint_solid_rect(fbL, 0, 0, w, h, vid)
62 let en: *u8 = "HELLO FRIEND" as *u8
63 let setL: i64 = nx_caption_render_uni(fbL, en, slen(en), 2, bar, fg)
64 rg(" Latin 'HELLO FRIEND' -> glyph px = " as *u8); rgn(setL); rg("\n" as *u8)
65 if setL > 0 { pass=pass+1; rg(" ROW latin-renders: GREEN\n" as *u8) } else { fail=fail+1; rg(" ROW latin-renders: RED\n" as *u8) }
66
67 // NEG-CONTROL: empty caption sets no glyph pixels
68 let fbE: *Framebuffer = mkfb(w, h)
69 nx_paint_solid_rect(fbE, 0, 0, w, h, vid)
70 if nx_caption_render_uni(fbE, "" as *u8, 0, 2, bar, fg) == 0 { pass=pass+1; rg(" ROW neg-control empty->0px: GREEN\n" as *u8) } else { fail=fail+1; rg(" ROW neg-control: RED\n" as *u8) }
71
72 // eyeball: stack Cyrillic (top) + Latin (bottom) into one PNG
73 let H2: i64 = h * 2
74 let rgb: *u8 = sys_mmap(w * H2 * 3)
75 var y: i64 = 0
76 while y < h {
77 var x: i64 = 0
78 while x < w {
79 let s: i64 = (y * w + x) * 4
80 let d1: i64 = (y * w + x) * 3
81 rgb[d1+0]=fbC.pixels[s+0]; rgb[d1+1]=fbC.pixels[s+1]; rgb[d1+2]=fbC.pixels[s+2]
82 let d2: i64 = ((h + y) * w + x) * 3
83 rgb[d2+0]=fbL.pixels[s+0]; rgb[d2+1]=fbL.pixels[s+1]; rgb[d2+2]=fbL.pixels[s+2]
84 x = x + 1
85 }
86 y = y + 1
87 }
88 nx_png_write_rgb("knowledge/nx_cyrillic_render.png" as *u8, rgb, w, H2)
89 rg(" eyeball -> knowledge/nx_cyrillic_render.png\n" as *u8)
90
91 rg("CYRILLIC-RENDER-GATE pass=" as *u8); rgn(pass); rg(" fail=" as *u8); rgn(fail)
92 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
93 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
94 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
95 let ctr__dry: *i64 = gv_ctr()
96 ctr__dry[0] = pass
97 ctr__dry[1] = pass + fail
98 let rc__dry: i64 = gv_verdict("CYRILLIC-RENDER-GATE" as *u8, ctr__dry, "native Cyrillic + Latin captions render; bar drawn; neg-control clean" as *u8)
99 sys_exit(rc__dry)
100 return rc__dry
101}