code wiki / (root) / nx_font_latin.nx

nx_font_latin.nx source

↩ module page · 275 lines · 22561 B

1// nx_font_latin.nx -- FULL UPPERCASE LATIN A-Z: makes the sovereign font USABLE (real English words), composed 2// from the complete stroke toolkit (rect + diagonal + ellipse). Contiguous A-Z (U+0041..005A) -> a clean 3-segment 3// cmap. One self-validated .ttf -> web_assets/nishi_latin.ttf + a page setting real words in our own font. 4// license_tier: ORIGINAL expect_exit: 0 5import "nx_syscalls_x86_64.nx" 6const MAGIC_MAGIC_65536: i64 = 65536 7const MAGIC_MAGIC_16777216: i64 = 16777216 8const MAGIC_MAGIC_4294967296: i64 = 4294967296 9const MAGIC_MAGIC_1024: i64 = 1024 10const MAGIC_MAGIC_32768: i64 = 32768 11const MAGIC_MAGIC_65535: i64 = 65535 12const MAGIC_MAGIC_65505: i64 = 65505 13const MAGIC_MAGIC_65473: i64 = 65473 14const MAGIC_MAGIC_1594834165: i64 = 1594834165 15const MAGIC_MAGIC_1033: i64 = 1033 16const MAGIC_MAGIC_196608: i64 = 196608 17const MAGIC_MAGIC_131072: i64 = 131072 18const MAGIC_MAGIC_262144: i64 = 262144 19 20const MAGIC_ADJ: i64 = 2981146554 21const WR: i64 = 38 22 23func sw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 24func 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 } 25 26func si16(v: i64) -> i64 { if v<0 { return v+MAGIC_MAGIC_65536 } return v } 27func w8(b: *u8, o: i64, v: i64) -> i64 { b[o]=(v%256) as u8; return o+1 } 28func 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 } 29func 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 } 30func 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) } 31func align4(o: i64) -> i64 { while o%4 != 0 { o=o+1 } return o } 32func 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 } 33func 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 } 34func 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 } 35func b64_encode(inb: *u8, n: i64, out: *u8) -> i64 { 36 var o: i64=0; var i: i64=0 37 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 38 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 } 39 let rem: i64=n-i 40 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 } 41 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 } 42 out[o]=0 as u8; return o 43} 44func isqrt(n: i64) -> i64 { if n<=0 { return 0 } var x: i64=n; var y: i64=(x+1)/2; while y<x { x=y; y=(x + n/x)/2 } return x } 45func add_rect(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 { 46 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 47 on[pc]=1; on[pc+1]=1; on[pc+2]=1; on[pc+3]=1; ep[cc]=pc+3; return pc+4 48} 49func vbar(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, xc: i64, y0: i64, y1: i64) -> i64 { return add_rect(px,py,on,ep,pc,cc, xc-WR,y0,xc+WR,y1) } 50func hbar(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, x1: i64, yc: i64) -> i64 { return add_rect(px,py,on,ep,pc,cc, x0,yc-WR,x1,yc+WR) } 51func seg(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 { 52 let dx: i64=x1-x0; let dy: i64=y1-y0 53 var ln: i64=isqrt(dx*dx+dy*dy); if ln==0 { ln=1 } 54 let ox: i64=WR*dy/ln; let oy: i64=WR*dx/ln 55 let ax: i64=x0+ox; let ay: i64=y0-oy; let bx: i64=x1+ox; let by: i64=y1-oy; let cx: i64=x1-ox; let cy: i64=y1+oy; let ex: i64=x0-ox; let ey: i64=y0+oy 56 let area: i64 = ax*by-bx*ay + bx*cy-cx*by + cx*ey-ex*cy + ex*ay-ax*ey 57 if area < 0 { 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 } 58 else { 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 } 59 on[pc]=1; on[pc+1]=1; on[pc+2]=1; on[pc+3]=1; ep[cc]=pc+3; return pc+4 60} 61func ellipse(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, cx: i64, cy: i64, rx: i64, ry: i64, ccw: i64) -> i64 { 62 px[pc]=cx+rx; py[pc]=cy; on[pc]=1 63 if ccw==1 { px[pc+1]=cx+rx; py[pc+1]=cy+ry; on[pc+1]=0; px[pc+2]=cx; py[pc+2]=cy+ry; on[pc+2]=1; px[pc+3]=cx-rx; py[pc+3]=cy+ry; on[pc+3]=0; px[pc+4]=cx-rx; py[pc+4]=cy; on[pc+4]=1; px[pc+5]=cx-rx; py[pc+5]=cy-ry; on[pc+5]=0; px[pc+6]=cx; py[pc+6]=cy-ry; on[pc+6]=1; px[pc+7]=cx+rx; py[pc+7]=cy-ry; on[pc+7]=0 } 64 else { px[pc+1]=cx+rx; py[pc+1]=cy-ry; on[pc+1]=0; px[pc+2]=cx; py[pc+2]=cy-ry; on[pc+2]=1; px[pc+3]=cx-rx; py[pc+3]=cy-ry; on[pc+3]=0; px[pc+4]=cx-rx; py[pc+4]=cy; on[pc+4]=1; px[pc+5]=cx-rx; py[pc+5]=cy+ry; on[pc+5]=0; px[pc+6]=cx; py[pc+6]=cy+ry; on[pc+6]=1; px[pc+7]=cx+rx; py[pc+7]=cy+ry; on[pc+7]=0 } 65 ep[cc]=pc+7; return pc+8 66} 67// open-right C-arc (thick): outer arc top->left->bottom + inner arc back, via quadratic Beziers. cx=right-opening center. 68func cshape(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, cx: i64, cy: i64, orx: i64, ory: i64, irx: i64, iry: i64) -> i64 { 69 px[pc]=cx; py[pc]=cy+ory; on[pc]=1 70 px[pc+1]=cx-orx; py[pc+1]=cy+ory; on[pc+1]=0 71 px[pc+2]=cx-orx; py[pc+2]=cy; on[pc+2]=1 72 px[pc+3]=cx-orx; py[pc+3]=cy-ory; on[pc+3]=0 73 px[pc+4]=cx; py[pc+4]=cy-ory; on[pc+4]=1 74 px[pc+5]=cx; py[pc+5]=cy-iry; on[pc+5]=1 75 px[pc+6]=cx-irx; py[pc+6]=cy-iry; on[pc+6]=0 76 px[pc+7]=cx-irx; py[pc+7]=cy; on[pc+7]=1 77 px[pc+8]=cx-irx; py[pc+8]=cy+iry; on[pc+8]=0 78 px[pc+9]=cx; py[pc+9]=cy+iry; on[pc+9]=1 79 ep[cc]=pc+9; return pc+10 80} 81 82// gid: 0 .notdef, 1 space, 2..27 = A..Z 83func gen_up(gid: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 84 if gid==0 { add_rect(px,py,on,ep,0,0, 80,0,520,700); meta[0]=1; meta[1]=4; return 0 } 85 if gid==1 { meta[0]=0; meta[1]=0; return 0 } 86 let L: i64=gid-2 87 var pc: i64=0 88 if L==0 { pc=seg(px,py,on,ep,pc,0, 90,0,300,700); pc=seg(px,py,on,ep,pc,1, 510,0,300,700); pc=hbar(px,py,on,ep,pc,2, 175,425,250); meta[0]=3; meta[1]=12; return 0 } 89 if L==1 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=hbar(px,py,on,ep,pc,1, 115,380,685); pc=hbar(px,py,on,ep,pc,2, 115,400,350); pc=hbar(px,py,on,ep,pc,3, 115,440,15); pc=vbar(px,py,on,ep,pc,4, 365,350,685); pc=vbar(px,py,on,ep,pc,5, 415,15,350); meta[0]=6; meta[1]=24; return 0 } 90 if L==2 { pc=cshape(px,py,on,ep,pc,0, 350,350,240,362,240-2*WR,362-2*WR); meta[0]=1; meta[1]=10; return 0 } 91 if L==3 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=hbar(px,py,on,ep,pc,1, 115,470,685); pc=hbar(px,py,on,ep,pc,2, 115,470,15); pc=vbar(px,py,on,ep,pc,3, 455,15,685); meta[0]=4; meta[1]=16; return 0 } 92 if L==4 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=hbar(px,py,on,ep,pc,1, 115,475,685); pc=hbar(px,py,on,ep,pc,2, 115,425,350); pc=hbar(px,py,on,ep,pc,3, 115,475,15); meta[0]=4; meta[1]=16; return 0 } 93 if L==5 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=hbar(px,py,on,ep,pc,1, 115,475,685); pc=hbar(px,py,on,ep,pc,2, 115,425,350); meta[0]=3; meta[1]=12; return 0 } 94 if L==6 { pc=cshape(px,py,on,ep,pc,0, 350,350,240,362,240-2*WR,362-2*WR); pc=vbar(px,py,on,ep,pc,1, 472,120,350); pc=hbar(px,py,on,ep,pc,2, 320,510,320); meta[0]=3; meta[1]=18; return 0 } 95 if L==7 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=vbar(px,py,on,ep,pc,1, 505,0,700); pc=hbar(px,py,on,ep,pc,2, 115,505,350); meta[0]=3; meta[1]=12; return 0 } 96 if L==8 { pc=vbar(px,py,on,ep,pc,0, 310,0,700); pc=hbar(px,py,on,ep,pc,1, 220,400,680); pc=hbar(px,py,on,ep,pc,2, 220,400,20); meta[0]=3; meta[1]=12; return 0 } 97 if L==9 { pc=vbar(px,py,on,ep,pc,0, 430,150,700); pc=hbar(px,py,on,ep,pc,1, 130,480,15); pc=vbar(px,py,on,ep,pc,2, 130,15,180); meta[0]=3; meta[1]=12; return 0 } 98 if L==10 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=seg(px,py,on,ep,pc,1, 115,360,510,700); pc=seg(px,py,on,ep,pc,2, 115,340,510,0); meta[0]=3; meta[1]=12; return 0 } 99 if L==11 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=hbar(px,py,on,ep,pc,1, 115,470,15); meta[0]=2; meta[1]=8; return 0 } 100 if L==12 { pc=vbar(px,py,on,ep,pc,0, 90,0,700); pc=vbar(px,py,on,ep,pc,1, 510,0,700); pc=seg(px,py,on,ep,pc,2, 90,700,300,300); pc=seg(px,py,on,ep,pc,3, 300,300,510,700); meta[0]=4; meta[1]=16; return 0 } 101 if L==13 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=vbar(px,py,on,ep,pc,1, 505,0,700); pc=seg(px,py,on,ep,pc,2, 125,690,495,10); meta[0]=3; meta[1]=12; return 0 } 102 if L==14 { pc=ellipse(px,py,on,ep,pc,0, 300,350,285,362,1); pc=ellipse(px,py,on,ep,pc,1, 300,350,285-2*WR,362-2*WR,0); meta[0]=2; meta[1]=16; return 0 } 103 if L==15 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=hbar(px,py,on,ep,pc,1, 115,430,685); pc=hbar(px,py,on,ep,pc,2, 115,430,360); pc=vbar(px,py,on,ep,pc,3, 410,360,685); meta[0]=4; meta[1]=16; return 0 } 104 if L==16 { pc=ellipse(px,py,on,ep,pc,0, 300,350,285,362,1); pc=ellipse(px,py,on,ep,pc,1, 300,350,285-2*WR,362-2*WR,0); pc=seg(px,py,on,ep,pc,2, 330,200,520,0-30); meta[0]=3; meta[1]=20; return 0 } 105 if L==17 { pc=vbar(px,py,on,ep,pc,0, 115,0,700); pc=hbar(px,py,on,ep,pc,1, 115,430,685); pc=hbar(px,py,on,ep,pc,2, 115,430,360); pc=vbar(px,py,on,ep,pc,3, 410,360,685); pc=seg(px,py,on,ep,pc,4, 250,360,500,0); meta[0]=5; meta[1]=20; return 0 } 106 if L==18 { pc=seg(px,py,on,ep,pc,0, 470,560,300,655); pc=seg(px,py,on,ep,pc,1, 300,655,150,555); pc=seg(px,py,on,ep,pc,2, 150,555,300,400); pc=seg(px,py,on,ep,pc,3, 300,400,470,255); pc=seg(px,py,on,ep,pc,4, 470,255,300,45); pc=seg(px,py,on,ep,pc,5, 300,45,140,150); meta[0]=6; meta[1]=24; return 0 } 107 if L==19 { pc=hbar(px,py,on,ep,pc,0, 70,530,685); pc=vbar(px,py,on,ep,pc,1, 300,0,685); meta[0]=2; meta[1]=8; return 0 } 108 if L==20 { pc=vbar(px,py,on,ep,pc,0, 115,150,700); pc=vbar(px,py,on,ep,pc,1, 505,150,700); pc=hbar(px,py,on,ep,pc,2, 115,505,15); meta[0]=3; meta[1]=12; return 0 } 109 if L==21 { pc=seg(px,py,on,ep,pc,0, 90,700,300,0); pc=seg(px,py,on,ep,pc,1, 510,700,300,0); meta[0]=2; meta[1]=8; return 0 } 110 if L==22 { pc=seg(px,py,on,ep,pc,0, 60,700,190,0); pc=seg(px,py,on,ep,pc,1, 190,0,300,450); pc=seg(px,py,on,ep,pc,2, 300,450,410,0); pc=seg(px,py,on,ep,pc,3, 410,0,540,700); meta[0]=4; meta[1]=16; return 0 } 111 if L==23 { pc=seg(px,py,on,ep,pc,0, 90,0,510,700); pc=seg(px,py,on,ep,pc,1, 90,700,510,0); meta[0]=2; meta[1]=8; return 0 } 112 if L==24 { pc=seg(px,py,on,ep,pc,0, 90,700,300,360); pc=seg(px,py,on,ep,pc,1, 510,700,300,360); pc=vbar(px,py,on,ep,pc,2, 300,0,380); meta[0]=3; meta[1]=12; return 0 } 113 pc=hbar(px,py,on,ep,pc,0, 90,510,685); pc=seg(px,py,on,ep,pc,1, 500,670,100,30); pc=hbar(px,py,on,ep,pc,2, 90,510,15); meta[0]=3; meta[1]=12; return 0 // Z 114} 115 116func append_glyph(g: *u8, go: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 117 let nc: i64=meta[0]; let np: i64=meta[1] 118 if nc==0 { return go } 119 var xmin: i64=px[0]; var xmax: i64=px[0]; var ymin: i64=py[0]; var ymax: i64=py[0] 120 var i: i64=0 121 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 } 122 var o: i64=go 123 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)) 124 i=0; while i<nc { o=w16(g,o,ep[i]); i=i+1 } 125 o=w16(g,o,0) 126 i=0; while i<np { if on[i]==1 { o=w8(g,o,1) } else { o=w8(g,o,0) } i=i+1 } 127 var prev: i64=0; i=0; while i<np { o=w16(g,o,si16(px[i]-prev)); prev=px[i]; i=i+1 } 128 prev=0; i=0; while i<np { o=w16(g,o,si16(py[i]-prev)); prev=py[i]; i=i+1 } 129 if o%2 != 0 { o=w8(g,o,0) } 130 return o 131} 132 133func main() -> i64 { 134 let NG: i64=28 135 let adv: *i64=sys_mmap(256) as *i64 136 adv[0]=640; adv[1]=600; adv[2]=680; adv[3]=660; adv[4]=620; adv[5]=600; adv[6]=680; adv[7]=680; adv[8]=380; adv[9]=560 137 adv[10]=640; adv[11]=580; adv[12]=780; adv[13]=700; adv[14]=720; adv[15]=640; adv[16]=740; adv[17]=680; adv[18]=640; adv[19]=620; adv[20]=700; adv[21]=660; adv[22]=800; adv[23]=660; adv[24]=640; adv[25]=620 138 139 let ep: *i64=sys_mmap(256) as *i64 140 let px: *i64=sys_mmap(MAGIC_MAGIC_1024) as *i64 141 let py: *i64=sys_mmap(MAGIC_MAGIC_1024) as *i64 142 let on: *i64=sys_mmap(MAGIC_MAGIC_1024) as *i64 143 let meta: *i64=sys_mmap(16) as *i64 144 let g: *u8=sys_mmap(MAGIC_MAGIC_32768) 145 let goff: *i64=sys_mmap(256) as *i64 146 var go: i64=0 147 var q: i64=0 148 while q<NG { goff[q]=go; gen_up(q,ep,px,py,on,meta); go=append_glyph(g,go,ep,px,py,on,meta); q=q+1 } 149 goff[NG]=go 150 let glyf_len: i64=go 151 152 let buf: *u8=sys_mmap(MAGIC_MAGIC_32768) 153 let toff: *i64=sys_mmap(128) as *i64 154 let tlen: *i64=sys_mmap(128) as *i64 155 let tcs: *i64=sys_mmap(128) as *i64 156 let NT: i64=10 157 var o: i64=12 + 16*NT 158 159 o=align4(o); toff[0]=o 160 o=w16(buf,o,4); o=w16(buf,o,si16(660)); o=w16(buf,o,400); o=w16(buf,o,5); o=w16(buf,o,0) 161 o=w16(buf,o,si16(650));o=w16(buf,o,si16(700));o=w16(buf,o,si16(0));o=w16(buf,o,si16(140)) 162 o=w16(buf,o,si16(650));o=w16(buf,o,si16(700));o=w16(buf,o,si16(0));o=w16(buf,o,si16(480)) 163 o=w16(buf,o,si16(50));o=w16(buf,o,si16(260)); o=w16(buf,o,si16(0)) 164 var pi: i64=0; while pi<10 { o=w8(buf,o,0); pi=pi+1 } 165 o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0) 166 o=w8(buf,o,78);o=w8(buf,o,73);o=w8(buf,o,83);o=w8(buf,o,72) 167 o=w16(buf,o,64); o=w16(buf,o,32); o=w16(buf,o,90) 168 o=w16(buf,o,si16(800));o=w16(buf,o,si16(-200));o=w16(buf,o,si16(0)) 169 o=w16(buf,o,800);o=w16(buf,o,200) 170 o=w32(buf,o,0);o=w32(buf,o,0) 171 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) 172 tlen[0]=o-toff[0]; o=align4(o); tcs[0]=csum(buf,toff[0],o-toff[0]) 173 174 // cmap format-4: 3 segments [32,32]->1, [65,90]->2..27, [FFFF] 175 o=align4(o); toff[1]=o 176 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) 177 let sub0: i64=o 178 o=w16(buf,o,4) 179 let lenpos: i64=o; o=w16(buf,o,0) 180 o=w16(buf,o,0); o=w16(buf,o,6); o=w16(buf,o,4); o=w16(buf,o,1); o=w16(buf,o,2) // segCountX2=6, searchRange=4, entrySelector=1, rangeShift=2 181 o=w16(buf,o,32); o=w16(buf,o,90); o=w16(buf,o,MAGIC_MAGIC_65535) // endCode 182 o=w16(buf,o,0) // reservedPad 183 o=w16(buf,o,32); o=w16(buf,o,65); o=w16(buf,o,MAGIC_MAGIC_65535) // startCode 184 o=w16(buf,o,MAGIC_MAGIC_65505); o=w16(buf,o,MAGIC_MAGIC_65473); o=w16(buf,o,1) // idDelta: 1-32, 2-65 185 o=w16(buf,o,0); o=w16(buf,o,0); o=w16(buf,o,0) // idRangeOffset 186 w16(buf, lenpos, o - sub0) 187 tlen[1]=o-toff[1]; o=align4(o); tcs[1]=csum(buf,toff[1],o-toff[1]) 188 189 o=align4(o); toff[2]=o 190 var gj: i64=0; while gj<glyf_len { buf[o]=g[gj]; o=o+1; gj=gj+1 } 191 tlen[2]=o-toff[2]; o=align4(o); tcs[2]=csum(buf,toff[2],o-toff[2]) 192 193 o=align4(o); toff[3]=o 194 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) 195 o=w16(buf,o,11); o=w16(buf,o,1000) 196 o=w32(buf,o,0);o=w32(buf,o,0); o=w32(buf,o,0);o=w32(buf,o,0) 197 o=w16(buf,o,si16(0));o=w16(buf,o,si16(-60));o=w16(buf,o,820);o=w16(buf,o,720) 198 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) 199 tlen[3]=o-toff[3]; o=align4(o); tcs[3]=csum(buf,toff[3],o-toff[3]) 200 201 o=align4(o); toff[4]=o 202 o=w32(buf,o,MAGIC_MAGIC_65536); o=w16(buf,o,si16(800)); o=w16(buf,o,si16(-200)); o=w16(buf,o,si16(0)) 203 o=w16(buf,o,820); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(820)) 204 o=w16(buf,o,si16(1)); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(0)) 205 o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0) 206 o=w16(buf,o,si16(0)); o=w16(buf,o,NG) 207 tlen[4]=o-toff[4]; o=align4(o); tcs[4]=csum(buf,toff[4],o-toff[4]) 208 209 o=align4(o); toff[5]=o 210 o=w16(buf,o,600);o=w16(buf,o,si16(0)); o=w16(buf,o,400);o=w16(buf,o,si16(0)) 211 var am: i64=0; while am<26 { o=w16(buf,o,adv[am]); o=w16(buf,o,si16(40)); am=am+1 } 212 tlen[5]=o-toff[5]; o=align4(o); tcs[5]=csum(buf,toff[5],o-toff[5]) 213 214 o=align4(o); toff[6]=o 215 var li: i64=0; while li<NG+1 { o=w16(buf,o,goff[li]/2); li=li+1 } 216 tlen[6]=o-toff[6]; o=align4(o); tcs[6]=csum(buf,toff[6],o-toff[6]) 217 218 o=align4(o); toff[7]=o 219 o=w32(buf,o,MAGIC_MAGIC_65536); o=w16(buf,o,NG); o=w16(buf,o,24); o=w16(buf,o,6) 220 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) 221 tlen[7]=o-toff[7]; o=align4(o); tcs[7]=csum(buf,toff[7],o-toff[7]) 222 223 o=align4(o); toff[8]=o 224 o=w16(buf,o,0); o=w16(buf,o,4); o=w16(buf,o,54) 225 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,20);o=w16(buf,o,0) 226 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,20) 227 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,20);o=w16(buf,o,0) 228 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,18);o=w16(buf,o,34) 229 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,83);o=w8(buf,o,0);o=w8(buf,o,97);o=w8(buf,o,0);o=w8(buf,o,110);o=w8(buf,o,0);o=w8(buf,o,115) 230 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) 231 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,83);o=w8(buf,o,0);o=w8(buf,o,97);o=w8(buf,o,0);o=w8(buf,o,110);o=w8(buf,o,0);o=w8(buf,o,115) 232 tlen[8]=o-toff[8]; o=align4(o); tcs[8]=csum(buf,toff[8],o-toff[8]) 233 234 o=align4(o); toff[9]=o 235 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) 236 tlen[9]=o-toff[9]; o=align4(o); tcs[9]=csum(buf,toff[9],o-toff[9]) 237 238 let total: i64=o 239 var hh: i64=0 240 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) 241 let tags: *u8="OS/2cmapglyfheadhheahmtxlocamaxpnamepost" as *u8 242 var d: i64=12; var ti: i64=0 243 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] 244 w32(buf,d+4,tcs[ti]); w32(buf,d+8,toff[ti]); w32(buf,d+12,tlen[ti]); d=d+16; ti=ti+1 } 245 let fsum0: i64=csum(buf,0,total) 246 var adj: i64=MAGIC_ADJ - fsum0 247 if adj<0 { adj=adj+MAGIC_MAGIC_4294967296 } 248 w32(buf, toff[3]+8, adj) 249 250 let fd: i64=sys_openat_wr("web_assets/nishi_latin.ttf" as *u8, 420) 251 if fd<0 { sw("SAVE-FAIL\n" as *u8); return 6 } 252 sys_write(fd, buf, total); sys_close(fd) 253 let fs: i64=csum(buf,0,total) 254 sw("nx_font_latin: full uppercase A-Z -> web_assets/nishi_latin.ttf (" as *u8); sn(total); sw("B) self-check=" as *u8) 255 if fs==MAGIC_ADJ { sw("PASS\n" as *u8) } else { sw("FAIL\n" as *u8) } 256 257 let b64: *u8=sys_mmap(MAGIC_MAGIC_131072) 258 b64_encode(buf, total, b64) 259 let pg: *u8=sys_mmap(MAGIC_MAGIC_262144) 260 var po: i64=0 261 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 Sans &mdash; a usable sovereign typeface</title><style>@font-face{font-family:'Nishi Sans';src:url(data:font/ttf;base64," as *u8) 262 po=he_puts(pg,po,b64) 263 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%,#161326,#0A0A0F);color:#F5F5FA;font-family:ui-sans-serif,system-ui,sans-serif}.wrap{text-align:center;padding:32px;max-width:1100px}.tag{display:inline-block;font-size:.8rem;letter-spacing:.2em;text-transform:uppercase;color:#9EA0B8;margin-bottom:16px}.big{font-family:'Nishi Sans';font-weight:400;line-height:1.15;letter-spacing:.06em;background:linear-gradient(100deg,#8A7BFF,#FF7A59);-webkit-background-clip:text;background-clip:text;color:transparent}.h1{font-size:clamp(3rem,13vw,8rem)}.h2{font-size:clamp(1.6rem,6vw,3.4rem);color:#F5F5FA;-webkit-text-fill-color:#F5F5FA}.row{font-family:'Nishi Sans';font-size:clamp(1.3rem,4vw,2.2rem);letter-spacing:.1em;color:#C7C9E0;margin-top:8px}.note{color:#9EA0B8;max-width:52ch;margin:30px auto 0;font-size:1.05rem;line-height:1.65}.note b{color:#F5F5FA}.mono{font-family:ui-monospace,Consolas,monospace;color:#8A7BFF}</style></head><body><div class=\"wrap\">" as *u8) 264 po=he_puts(pg,po,"<span class=\"tag\">&#9733; a full uppercase alphabet &mdash; real words now</span>" as *u8) 265 po=he_puts(pg,po,"<div class=\"big h1\">NISHI SANS</div>" as *u8) 266 po=he_puts(pg,po,"<div class=\"row\">ABCDEFGHIJKLM</div><div class=\"row\">NOPQRSTUVWXYZ</div>" as *u8) 267 po=he_puts(pg,po,"<div class=\"big h2\" style=\"margin-top:26px\">THE QUICK BROWN FOX JUMPS OVER A LAZY DOG</div>" as *u8) 268 po=he_puts(pg,po,"<p class=\"note\">Every letter is generated from our four sovereign stroke primitives (horizontal, vertical, diagonal, curve) into one self-validated <span class=\"mono\">.ttf</span> &mdash; a full A&ndash;Z that can set real English words. Next: lowercase, digits, punctuation, then wire <b>Nishi Sans</b> into the site kit as our house typeface.</p>" as *u8) 269 po=he_puts(pg,po,"</div></body></html>" as *u8) 270 let pfd: i64=sys_openat_wr("web_assets/nishi_latin.html" as *u8, 420) 271 if pfd<0 { sw("PAGE-FAIL\n" as *u8); return 7 } 272 sys_write(pfd, pg, po); sys_close(pfd) 273 sw(" -> web_assets/nishi_latin.html (open to SEE real words in our font)\n" as *u8) 274 return 0 275}