code wiki / (root) / nx_font_diag.nx

nx_font_diag.nx source

↩ module page · 297 lines · 19203 B

1// nx_font_diag.nx -- DIAGONAL-STROKE generator upgrade (the capability multiplier). Adds integer isqrt + add_seg: 2// a thick segment in ANY direction -> a 4-point parallelogram contour, force-wound CCW (shoelace sign) so it 3// matches add_rect and overlaps fill under nonzero-winding. Unlocks diagonals -> proves it with Latin diagonal 4// letters (N A V X Y Z K W M -> toward full Latin) + Japanese KATAKANA (ト ノ ハ, which need diagonals) in one 5// self-validated .ttf -> web_assets/nishi_diag.ttf + nishi_diag.html. license_tier: ORIGINAL expect_exit: 0 6import "nx_syscalls_x86_64.nx" 7const MAGIC_MAGIC_65536: i64 = 65536 8const MAGIC_MAGIC_16777216: i64 = 16777216 9const MAGIC_MAGIC_4294967296: i64 = 4294967296 10const MAGIC_MAGIC_12488: i64 = 12488 11const MAGIC_MAGIC_12494: i64 = 12494 12const MAGIC_MAGIC_12495: i64 = 12495 13const MAGIC_MAGIC_1024: i64 = 1024 14const MAGIC_MAGIC_16384: i64 = 16384 15const MAGIC_MAGIC_24576: i64 = 24576 16const MAGIC_MAGIC_65535: i64 = 65535 17const MAGIC_MAGIC_1594834165: i64 = 1594834165 18const MAGIC_MAGIC_1033: i64 = 1033 19const MAGIC_MAGIC_196608: i64 = 196608 20const MAGIC_MAGIC_131072: i64 = 131072 21const MAGIC_MAGIC_262144: i64 = 262144 22 23const MAGIC_ADJ: i64 = 2981146554 24 25func sw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 26func sn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 } 27 28func si16(v: i64) -> i64 { if v<0 { return v+MAGIC_MAGIC_65536 } return v } 29func w8(b: *u8, o: i64, v: i64) -> i64 { b[o]=(v%256) as u8; return o+1 } 30func w16(b: *u8, o: i64, v: i64) -> i64 { b[o]=((v/256)%256) as u8; b[o+1]=(v%256) as u8; return o+2 } 31func w32(b: *u8, o: i64, v: i64) -> i64 { b[o]=((v/MAGIC_MAGIC_16777216)%256) as u8; b[o+1]=((v/MAGIC_MAGIC_65536)%256) as u8; b[o+2]=((v/256)%256) as u8; b[o+3]=(v%256) as u8; return o+4 } 32func r32(b: *u8, o: i64) -> i64 { return (b[o] as i64)*MAGIC_MAGIC_16777216 + (b[o+1] as i64)*MAGIC_MAGIC_65536 + (b[o+2] as i64)*256 + (b[o+3] as i64) } 33func align4(o: i64) -> i64 { while o%4 != 0 { o=o+1 } return o } 34func csum(b: *u8, off: i64, len: i64) -> i64 { var s: i64=0; var i: i64=off; while i < off+len { s = (s + r32(b,i)) % MAGIC_MAGIC_4294967296; i=i+4 } return s } 35func he_puts(buf: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var i: i64=0; while s[i]!=0 { buf[o]=s[i]; o=o+1; i=i+1 } return o } 36func b64c(v: i64) -> i64 { if v<26 { return 65+v } if v<52 { return 97+(v-26) } if v<62 { return 48+(v-52) } if v==62 { return 43 } return 47 } 37func b64_encode(inb: *u8, n: i64, out: *u8) -> i64 { 38 var o: i64=0; var i: i64=0 39 while i+3<=n { let a: i64=inb[i] as i64; let b: i64=inb[i+1] as i64; let c: i64=inb[i+2] as i64 40 out[o]=b64c(a/4) as u8; o=o+1; out[o]=b64c((a%4)*16 + b/16) as u8; o=o+1; out[o]=b64c((b%16)*4 + c/64) as u8; o=o+1; out[o]=b64c(c%64) as u8; o=o+1; i=i+3 } 41 let rem: i64=n-i 42 if rem==1 { let a: i64=inb[i] as i64; out[o]=b64c(a/4) as u8; o=o+1; out[o]=b64c((a%4)*16) as u8; o=o+1; out[o]=61 as u8; o=o+1; out[o]=61 as u8; o=o+1 } 43 if rem==2 { let a: i64=inb[i] as i64; let b: i64=inb[i+1] as i64; out[o]=b64c(a/4) as u8; o=o+1; out[o]=b64c((a%4)*16 + b/16) as u8; o=o+1; out[o]=b64c((b%16)*4) as u8; o=o+1; out[o]=61 as u8; o=o+1 } 44 out[o]=0 as u8; return o 45} 46func isqrt(n: i64) -> i64 { 47 if n<=0 { return 0 } 48 var x: i64=n 49 var y: i64=(x+1)/2 50 while y<x { x=y; y=(x + n/x)/2 } 51 return x 52} 53func add_rect(px: *i64, py: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 { 54 px[pc]=x0; py[pc]=y0; px[pc+1]=x1; py[pc+1]=y0; px[pc+2]=x1; py[pc+2]=y1; px[pc+3]=x0; py[pc+3]=y1 55 ep[cc]=pc+3; return pc+4 56} 57// thick segment (any direction) -> parallelogram, force-wound CCW so overlaps fill (nonzero winding). 58func add_seg(px: *i64, py: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, y0: i64, x1: i64, y1: i64, wr: i64) -> i64 { 59 let dx: i64=x1-x0; let dy: i64=y1-y0 60 var ln: i64=isqrt(dx*dx+dy*dy); if ln==0 { ln=1 } 61 let ox: i64=wr*dy/ln; let oy: i64=wr*dx/ln 62 let ax: i64=x0+ox; let ay: i64=y0-oy 63 let bx: i64=x1+ox; let by: i64=y1-oy 64 let cx: i64=x1-ox; let cy: i64=y1+oy 65 let ex: i64=x0-ox; let ey: i64=y0+oy 66 let area: i64 = ax*by-bx*ay + bx*cy-cx*by + cx*ey-ex*cy + ex*ay-ax*ey 67 if area < 0 { 68 px[pc]=ax; py[pc]=ay; px[pc+1]=ex; py[pc+1]=ey; px[pc+2]=cx; py[pc+2]=cy; px[pc+3]=bx; py[pc+3]=by 69 } else { 70 px[pc]=ax; py[pc]=ay; px[pc+1]=bx; py[pc+1]=by; px[pc+2]=cx; py[pc+2]=cy; px[pc+3]=ex; py[pc+3]=ey 71 } 72 ep[cc]=pc+3; return pc+4 73} 74 75// glyph index: 0 .notdef, 1 space, 2 A,3 K,4 M,5 N,6 V,7 W,8 X,9 Y,10 Z, 11 ト,12 ノ,13 ハ 76func gen_diag(gg: i64, wr: i64, ep: *i64, px: *i64, py: *i64, meta: *i64) -> i64 { 77 if gg==0 { add_rect(px,py,ep,0,0, 80,0,520,700); meta[0]=1; meta[1]=4; return 0 } 78 if gg==1 { meta[0]=0; meta[1]=0; return 0 } 79 if gg==2 { var pc: i64=0 // A 80 pc=add_seg(px,py,ep,pc,0, 90,0,300,700,wr); pc=add_seg(px,py,ep,pc,1, 510,0,300,700,wr); pc=add_rect(px,py,ep,pc,2, 165,250-wr,435,250+wr) 81 meta[0]=3; meta[1]=12; return 0 } 82 if gg==3 { var pc: i64=0 // K 83 pc=add_rect(px,py,ep,pc,0, 120-wr,0,120+wr,700); pc=add_seg(px,py,ep,pc,1, 120,360,540,700,wr); pc=add_seg(px,py,ep,pc,2, 120,340,540,0,wr) 84 meta[0]=3; meta[1]=12; return 0 } 85 if gg==4 { var pc: i64=0 // M 86 pc=add_rect(px,py,ep,pc,0, 90-wr,0,90+wr,700); pc=add_rect(px,py,ep,pc,1, 510-wr,0,510+wr,700); pc=add_seg(px,py,ep,pc,2, 90,700,300,280,wr); pc=add_seg(px,py,ep,pc,3, 300,280,510,700,wr) 87 meta[0]=4; meta[1]=16; return 0 } 88 if gg==5 { var pc: i64=0 // N 89 pc=add_rect(px,py,ep,pc,0, 120-wr,0,120+wr,700); pc=add_rect(px,py,ep,pc,1, 500-wr,0,500+wr,700); pc=add_seg(px,py,ep,pc,2, 130,700,500,0,wr) 90 meta[0]=3; meta[1]=12; return 0 } 91 if gg==6 { var pc: i64=0 // V 92 pc=add_seg(px,py,ep,pc,0, 80,700,300,0,wr); pc=add_seg(px,py,ep,pc,1, 520,700,300,0,wr) 93 meta[0]=2; meta[1]=8; return 0 } 94 if gg==7 { var pc: i64=0 // W 95 pc=add_seg(px,py,ep,pc,0, 60,700,190,0,wr); pc=add_seg(px,py,ep,pc,1, 190,0,300,480,wr); pc=add_seg(px,py,ep,pc,2, 300,480,410,0,wr); pc=add_seg(px,py,ep,pc,3, 410,0,540,700,wr) 96 meta[0]=4; meta[1]=16; return 0 } 97 if gg==8 { var pc: i64=0 // X 98 pc=add_seg(px,py,ep,pc,0, 80,0,520,700,wr); pc=add_seg(px,py,ep,pc,1, 80,700,520,0,wr) 99 meta[0]=2; meta[1]=8; return 0 } 100 if gg==9 { var pc: i64=0 // Y 101 pc=add_seg(px,py,ep,pc,0, 80,700,300,360,wr); pc=add_seg(px,py,ep,pc,1, 520,700,300,360,wr); pc=add_rect(px,py,ep,pc,2, 300-wr,0,300+wr,380) 102 meta[0]=3; meta[1]=12; return 0 } 103 if gg==10 { var pc: i64=0 // Z 104 pc=add_rect(px,py,ep,pc,0, 90,700-2*wr,510,700); pc=add_seg(px,py,ep,pc,1, 490,680,110,20,wr); pc=add_rect(px,py,ep,pc,2, 90,0,510,2*wr) 105 meta[0]=3; meta[1]=12; return 0 } 106 if gg==11 { var pc: i64=0 // ト katakana TO 107 pc=add_rect(px,py,ep,pc,0, 360-wr,150,360+wr,830); pc=add_seg(px,py,ep,pc,1, 360,560,690,650,wr) 108 meta[0]=2; meta[1]=8; return 0 } 109 if gg==12 { add_seg(px,py,ep,0,0, 720,820,260,160,wr); meta[0]=1; meta[1]=4; return 0 } // ノ katakana NO 110 var pc: i64=0 // ハ katakana HA 111 pc=add_seg(px,py,ep,pc,0, 430,790,240,170,wr); pc=add_seg(px,py,ep,pc,1, 540,760,810,170,wr) 112 meta[0]=2; meta[1]=8; return 0 113} 114 115func append_glyph(g: *u8, go: i64, ep: *i64, px: *i64, py: *i64, meta: *i64) -> i64 { 116 let nc: i64=meta[0]; let np: i64=meta[1] 117 if nc==0 { return go } 118 var xmin: i64=px[0]; var xmax: i64=px[0]; var ymin: i64=py[0]; var ymax: i64=py[0] 119 var i: i64=0 120 while i<np { if px[i]<xmin{xmin=px[i]} if px[i]>xmax{xmax=px[i]} if py[i]<ymin{ymin=py[i]} if py[i]>ymax{ymax=py[i]} i=i+1 } 121 var o: i64=go 122 o=w16(g,o,si16(nc)); o=w16(g,o,si16(xmin)); o=w16(g,o,si16(ymin)); o=w16(g,o,si16(xmax)); o=w16(g,o,si16(ymax)) 123 i=0; while i<nc { o=w16(g,o,ep[i]); i=i+1 } 124 o=w16(g,o,0) 125 i=0; while i<np { o=w8(g,o,1); i=i+1 } 126 var prev: i64=0; i=0; while i<np { o=w16(g,o,si16(px[i]-prev)); prev=px[i]; i=i+1 } 127 prev=0; i=0; while i<np { o=w16(g,o,si16(py[i]-prev)); prev=py[i]; i=i+1 } 128 if o%2 != 0 { o=w8(g,o,0) } 129 return o 130} 131 132func main() -> i64 { 133 let NG: i64=14 134 let NCP: i64=13 135 let cp: *i64=sys_mmap(256) as *i64 136 let gd: *i64=sys_mmap(256) as *i64 137 cp[0]=32; gd[0]=1 138 cp[1]=65; gd[1]=2 // A 139 cp[2]=75; gd[2]=3 // K 140 cp[3]=77; gd[3]=4 // M 141 cp[4]=78; gd[4]=5 // N 142 cp[5]=86; gd[5]=6 // V 143 cp[6]=87; gd[6]=7 // W 144 cp[7]=88; gd[7]=8 // X 145 cp[8]=89; gd[8]=9 // Y 146 cp[9]=90; gd[9]=10 // Z 147 cp[10]=MAGIC_MAGIC_12488; gd[10]=11 // ト 148 cp[11]=MAGIC_MAGIC_12494; gd[11]=12 // ノ 149 cp[12]=MAGIC_MAGIC_12495; gd[12]=13 // ハ 150 151 let ep: *i64=sys_mmap(256) as *i64 152 let px: *i64=sys_mmap(MAGIC_MAGIC_1024) as *i64 153 let py: *i64=sys_mmap(MAGIC_MAGIC_1024) as *i64 154 let meta: *i64=sys_mmap(16) as *i64 155 let g: *u8=sys_mmap(MAGIC_MAGIC_16384) 156 let goff: *i64=sys_mmap(256) as *i64 157 let wr: i64=52 158 var go: i64=0 159 var q: i64=0 160 while q<NG { goff[q]=go; gen_diag(q,wr,ep,px,py,meta); go=append_glyph(g,go,ep,px,py,meta); q=q+1 } 161 goff[NG]=go 162 let glyf_len: i64=go 163 164 let buf: *u8=sys_mmap(MAGIC_MAGIC_24576) 165 let toff: *i64=sys_mmap(128) as *i64 166 let tlen: *i64=sys_mmap(128) as *i64 167 let tcs: *i64=sys_mmap(128) as *i64 168 let NT: i64=10 169 var o: i64=12 + 16*NT 170 171 o=align4(o); toff[0]=o 172 o=w16(buf,o,4); o=w16(buf,o,si16(650)); o=w16(buf,o,400); o=w16(buf,o,5); o=w16(buf,o,0) 173 o=w16(buf,o,si16(650));o=w16(buf,o,si16(700));o=w16(buf,o,si16(0));o=w16(buf,o,si16(140)) 174 o=w16(buf,o,si16(650));o=w16(buf,o,si16(700));o=w16(buf,o,si16(0));o=w16(buf,o,si16(480)) 175 o=w16(buf,o,si16(50));o=w16(buf,o,si16(260)); o=w16(buf,o,si16(0)) 176 var pi: i64=0; while pi<10 { o=w8(buf,o,0); pi=pi+1 } 177 o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0) 178 o=w8(buf,o,78);o=w8(buf,o,73);o=w8(buf,o,83);o=w8(buf,o,72) 179 o=w16(buf,o,64); o=w16(buf,o,32); o=w16(buf,o,MAGIC_MAGIC_12495) 180 o=w16(buf,o,si16(800));o=w16(buf,o,si16(-200));o=w16(buf,o,si16(0)) 181 o=w16(buf,o,850);o=w16(buf,o,180) 182 o=w32(buf,o,0);o=w32(buf,o,0) 183 o=w16(buf,o,si16(500));o=w16(buf,o,si16(700)); o=w16(buf,o,0);o=w16(buf,o,32);o=w16(buf,o,1) 184 tlen[0]=o-toff[0]; o=align4(o); tcs[0]=csum(buf,toff[0],o-toff[0]) 185 186 o=align4(o); toff[1]=o 187 o=w16(buf,o,0); o=w16(buf,o,1); o=w16(buf,o,3); o=w16(buf,o,1); o=w32(buf,o,12) 188 let sub0: i64=o 189 let segCount: i64=NCP+1 190 o=w16(buf,o,4) 191 let lenpos: i64=o; o=w16(buf,o,0) 192 o=w16(buf,o,0) 193 o=w16(buf,o,segCount*2) 194 var p2: i64=1; while p2*2<=segCount { p2=p2*2 } 195 o=w16(buf,o,p2*2) 196 var es: i64=0; var tp: i64=p2; while tp>1 { tp=tp/2; es=es+1 } 197 o=w16(buf,o,es) 198 o=w16(buf,o,segCount*2 - p2*2) 199 var ci: i64=0; while ci<NCP { o=w16(buf,o,cp[ci]); ci=ci+1 } 200 o=w16(buf,o,MAGIC_MAGIC_65535) 201 o=w16(buf,o,0) 202 ci=0; while ci<NCP { o=w16(buf,o,cp[ci]); ci=ci+1 } 203 o=w16(buf,o,MAGIC_MAGIC_65535) 204 ci=0; while ci<NCP { var dd: i64=gd[ci]-cp[ci]; if dd<0 { dd=dd+MAGIC_MAGIC_65536 } o=w16(buf,o,dd); ci=ci+1 } 205 o=w16(buf,o,1) 206 ci=0; while ci<segCount { o=w16(buf,o,0); ci=ci+1 } 207 w16(buf, lenpos, o - sub0) 208 tlen[1]=o-toff[1]; o=align4(o); tcs[1]=csum(buf,toff[1],o-toff[1]) 209 210 o=align4(o); toff[2]=o 211 var gj: i64=0; while gj<glyf_len { buf[o]=g[gj]; o=o+1; gj=gj+1 } 212 tlen[2]=o-toff[2]; o=align4(o); tcs[2]=csum(buf,toff[2],o-toff[2]) 213 214 o=align4(o); toff[3]=o 215 o=w32(buf,o,MAGIC_MAGIC_65536); o=w32(buf,o,MAGIC_MAGIC_65536); o=w32(buf,o,0); o=w32(buf,o,MAGIC_MAGIC_1594834165) 216 o=w16(buf,o,11); o=w16(buf,o,1000) 217 o=w32(buf,o,0);o=w32(buf,o,0); o=w32(buf,o,0);o=w32(buf,o,0) 218 o=w16(buf,o,si16(0));o=w16(buf,o,si16(0));o=w16(buf,o,1000);o=w16(buf,o,850) 219 o=w16(buf,o,0); o=w16(buf,o,8); o=w16(buf,o,2); o=w16(buf,o,0); o=w16(buf,o,0) 220 tlen[3]=o-toff[3]; o=align4(o); tcs[3]=csum(buf,toff[3],o-toff[3]) 221 222 o=align4(o); toff[4]=o 223 o=w32(buf,o,MAGIC_MAGIC_65536); o=w16(buf,o,si16(850)); o=w16(buf,o,si16(-150)); o=w16(buf,o,si16(0)) 224 o=w16(buf,o,1000); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(1000)) 225 o=w16(buf,o,si16(1)); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(0)) 226 o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0) 227 o=w16(buf,o,si16(0)); o=w16(buf,o,NG) 228 tlen[4]=o-toff[4]; o=align4(o); tcs[4]=csum(buf,toff[4],o-toff[4]) 229 230 o=align4(o); toff[5]=o 231 o=w16(buf,o,600);o=w16(buf,o,si16(0)); o=w16(buf,o,400);o=w16(buf,o,si16(0)) 232 var lm: i64=0; while lm<9 { o=w16(buf,o,640); o=w16(buf,o,si16(0)); lm=lm+1 } 233 var km: i64=0; while km<3 { o=w16(buf,o,1000); o=w16(buf,o,si16(0)); km=km+1 } 234 tlen[5]=o-toff[5]; o=align4(o); tcs[5]=csum(buf,toff[5],o-toff[5]) 235 236 o=align4(o); toff[6]=o 237 var li: i64=0; while li<NG+1 { o=w16(buf,o,goff[li]/2); li=li+1 } 238 tlen[6]=o-toff[6]; o=align4(o); tcs[6]=csum(buf,toff[6],o-toff[6]) 239 240 o=align4(o); toff[7]=o 241 o=w32(buf,o,MAGIC_MAGIC_65536); o=w16(buf,o,NG); o=w16(buf,o,20); o=w16(buf,o,5) 242 o=w16(buf,o,0);o=w16(buf,o,0); o=w16(buf,o,2); o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0) 243 tlen[7]=o-toff[7]; o=align4(o); tcs[7]=csum(buf,toff[7],o-toff[7]) 244 245 o=align4(o); toff[8]=o 246 o=w16(buf,o,0); o=w16(buf,o,4); o=w16(buf,o,54) 247 o=w16(buf,o,3);o=w16(buf,o,1);o=w16(buf,o,MAGIC_MAGIC_1033);o=w16(buf,o,1);o=w16(buf,o,18);o=w16(buf,o,0) 248 o=w16(buf,o,3);o=w16(buf,o,1);o=w16(buf,o,MAGIC_MAGIC_1033);o=w16(buf,o,2);o=w16(buf,o,14);o=w16(buf,o,18) 249 o=w16(buf,o,3);o=w16(buf,o,1);o=w16(buf,o,MAGIC_MAGIC_1033);o=w16(buf,o,4);o=w16(buf,o,18);o=w16(buf,o,0) 250 o=w16(buf,o,3);o=w16(buf,o,1);o=w16(buf,o,MAGIC_MAGIC_1033);o=w16(buf,o,6);o=w16(buf,o,16);o=w16(buf,o,32) 251 o=w8(buf,o,0);o=w8(buf,o,78);o=w8(buf,o,0);o=w8(buf,o,105);o=w8(buf,o,0);o=w8(buf,o,115);o=w8(buf,o,0);o=w8(buf,o,104);o=w8(buf,o,0);o=w8(buf,o,105);o=w8(buf,o,0);o=w8(buf,o,32);o=w8(buf,o,0);o=w8(buf,o,68);o=w8(buf,o,0);o=w8(buf,o,105);o=w8(buf,o,0);o=w8(buf,o,97);o=w8(buf,o,0);o=w8(buf,o,103) 252 o=w8(buf,o,0);o=w8(buf,o,82);o=w8(buf,o,0);o=w8(buf,o,101);o=w8(buf,o,0);o=w8(buf,o,103);o=w8(buf,o,0);o=w8(buf,o,117);o=w8(buf,o,0);o=w8(buf,o,108);o=w8(buf,o,0);o=w8(buf,o,97);o=w8(buf,o,0);o=w8(buf,o,114) 253 o=w8(buf,o,0);o=w8(buf,o,78);o=w8(buf,o,0);o=w8(buf,o,105);o=w8(buf,o,0);o=w8(buf,o,115);o=w8(buf,o,0);o=w8(buf,o,104);o=w8(buf,o,0);o=w8(buf,o,105);o=w8(buf,o,0);o=w8(buf,o,68);o=w8(buf,o,0);o=w8(buf,o,105);o=w8(buf,o,0);o=w8(buf,o,97);o=w8(buf,o,0);o=w8(buf,o,103) 254 tlen[8]=o-toff[8]; o=align4(o); tcs[8]=csum(buf,toff[8],o-toff[8]) 255 256 o=align4(o); toff[9]=o 257 o=w32(buf,o,MAGIC_MAGIC_196608); o=w32(buf,o,0); o=w16(buf,o,si16(-100)); o=w16(buf,o,50); o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0) 258 tlen[9]=o-toff[9]; o=align4(o); tcs[9]=csum(buf,toff[9],o-toff[9]) 259 260 let total: i64=o 261 var hh: i64=0 262 hh=w32(buf,hh,MAGIC_MAGIC_65536); hh=w16(buf,hh,NT); hh=w16(buf,hh,128); hh=w16(buf,hh,3); hh=w16(buf,hh,32) 263 let tags: *u8="OS/2cmapglyfheadhheahmtxlocamaxpnamepost" as *u8 264 var d: i64=12; var ti: i64=0 265 while ti<NT { buf[d]=tags[ti*4]; buf[d+1]=tags[ti*4+1]; buf[d+2]=tags[ti*4+2]; buf[d+3]=tags[ti*4+3] 266 w32(buf,d+4,tcs[ti]); w32(buf,d+8,toff[ti]); w32(buf,d+12,tlen[ti]); d=d+16; ti=ti+1 } 267 let fsum0: i64=csum(buf,0,total) 268 var adj: i64=MAGIC_ADJ - fsum0 269 if adj<0 { adj=adj+MAGIC_MAGIC_4294967296 } 270 w32(buf, toff[3]+8, adj) 271 272 let fd: i64=sys_openat_wr("web_assets/nishi_diag.ttf" as *u8, 420) 273 if fd<0 { sw("SAVE-FAIL\n" as *u8); return 6 } 274 sys_write(fd, buf, total); sys_close(fd) 275 let fs: i64=csum(buf,0,total) 276 sw("nx_font_diag: diagonal strokes -> Latin(NAVXYZKWM)+katakana -> web_assets/nishi_diag.ttf (" as *u8); sn(total); sw("B) self-check=" as *u8) 277 if fs==MAGIC_ADJ { sw("PASS\n" as *u8) } else { sw("FAIL\n" as *u8) } 278 279 let b64: *u8=sys_mmap(MAGIC_MAGIC_131072) 280 b64_encode(buf, total, b64) 281 let pg: *u8=sys_mmap(MAGIC_MAGIC_262144) 282 var po: i64=0 283 po=he_puts(pg,po,"<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><meta name=\"color-scheme\" content=\"dark\"><title>Nishi Diag &mdash; diagonal strokes</title><style>@font-face{font-family:'Nishi Diag';src:url(data:font/ttf;base64," as *u8) 284 po=he_puts(pg,po,b64) 285 po=he_puts(pg,po,") format('truetype')}*{box-sizing:border-box}body{margin:0;min-height:100vh;display:grid;place-items:center;background:radial-gradient(1100px 560px at 50% -10%,#101d26,#0A0A0F);color:#F5F5FA;font-family:ui-sans-serif,system-ui,sans-serif}.wrap{text-align:center;padding:32px;max-width:1000px}.tag{display:inline-block;font-size:.8rem;letter-spacing:.2em;text-transform:uppercase;color:#9EA0B8;margin-bottom:18px}.big{font-family:'Nishi Diag';font-size:clamp(3rem,13vw,8rem);line-height:1.2;letter-spacing:.08em;background:linear-gradient(100deg,#4BD6C7,#8A7BFF);-webkit-background-clip:text;background-clip:text;color:transparent}.lbl{font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:#6f7290;margin:2px 0 18px}.note{color:#9EA0B8;max-width:54ch;margin:30px auto 0;font-size:1.05rem;line-height:1.65}.note b{color:#F5F5FA}.mono{font-family:ui-monospace,Consolas,monospace;color:#4BD6C7}</style></head><body><div class=\"wrap\">" as *u8) 286 po=he_puts(pg,po,"<span class=\"tag\">&#9733; diagonal strokes unlocked</span>" as *u8) 287 po=he_puts(pg,po,"<div class=\"big\">NAVY</div><div class=\"lbl\">Latin diagonals &mdash; N A V Y</div>" as *u8) 288 po=he_puts(pg,po,"<div class=\"big\">WXZ KM</div><div class=\"lbl\">more diagonals &mdash; W X Z K M</div>" as *u8) 289 po=he_puts(pg,po,"<div class=\"big\">&#x30C8;&#x30CE;&#x30CF;</div><div class=\"lbl\">Katakana &mdash; Japanese (to / no / ha)</div>" as *u8) 290 po=he_puts(pg,po,"<p class=\"note\">Every letter here needs a <b>diagonal</b> stroke &mdash; impossible before this rung, which added integer <span class=\"mono\">isqrt</span> + <span class=\"mono\">add_seg</span> (a thick segment in any direction, force-wound so overlaps fill). It unlocks Latin (N A V K X Y Z W M), Japanese katakana, and more Korean at once &mdash; all in one self-validated sovereign <span class=\"mono\">.ttf</span>.</p>" as *u8) 291 po=he_puts(pg,po,"</div></body></html>" as *u8) 292 let pfd: i64=sys_openat_wr("web_assets/nishi_diag.html" as *u8, 420) 293 if pfd<0 { sw("PAGE-FAIL\n" as *u8); return 7 } 294 sys_write(pfd, pg, po); sys_close(pfd) 295 sw(" -> web_assets/nishi_diag.html (open to SEE diagonal letters + katakana)\n" as *u8) 296 return 0 297}