code wiki / (root) / nx_font_variants.nx

nx_font_variants.nx source

↩ module page · 271 lines · 18666 B

1// nx_font_variants.nx -- VARIATION SYSTEM: one glyph definition -> N visibly-distinct fonts via a STYLE VECTOR 2// {wr=stem weight, wh=horizontal weight (contrast), slant=oblique shear, xw=width %}. So if a variant reads too 3// close to some other font, change the vector and regenerate a distinct, drop-in replacement -- no re-drawing. 4// Weight/contrast bake into the stroke primitives; slant+width are a post-transform on the outline points. 5// Emits 5 variants of "NISHI" (Regular/Oblique/Condensed/Bold/Wide-Light) as separate self-validated .ttf + 6// a comparison page. license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls_x86_64.nx" 8const MAGIC_MAGIC_65536: i64 = 65536 9const MAGIC_MAGIC_16777216: i64 = 16777216 10const MAGIC_MAGIC_4294967296: i64 = 4294967296 11const MAGIC_MAGIC_8192: i64 = 8192 12const MAGIC_MAGIC_65535: i64 = 65535 13const MAGIC_MAGIC_1594834165: i64 = 1594834165 14const MAGIC_MAGIC_1100: i64 = 1100 15const MAGIC_MAGIC_1033: i64 = 1033 16const MAGIC_MAGIC_196608: i64 = 196608 17const MAGIC_MAGIC_262144: i64 = 262144 18const MAGIC_MAGIC_16384: i64 = 16384 19 20const MAGIC_ADJ: i64 = 2981146554 21 22func sw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 23func 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 } 24func si16(v: i64) -> i64 { if v<0 { return v+MAGIC_MAGIC_65536 } return v } 25func w8(b: *u8, o: i64, v: i64) -> i64 { b[o]=(v%256) as u8; return o+1 } 26func 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 } 27func 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 } 28func 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) } 29func align4(o: i64) -> i64 { while o%4 != 0 { o=o+1 } return o } 30func 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 } 31func 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 } 32func 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 } 33func b64_encode(inb: *u8, n: i64, out: *u8) -> i64 { 34 var o: i64=0; var i: i64=0 35 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 36 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 } 37 let rem: i64=n-i 38 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 } 39 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 } 40 out[o]=0 as u8; return o 41} 42func 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 } 43func rectw(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 { 44 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 45 on[pc]=1; on[pc+1]=1; on[pc+2]=1; on[pc+3]=1; ep[cc]=pc+3; return pc+4 46} 47func vbar(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, xc: i64, y0: i64, y1: i64, w: i64) -> i64 { return rectw(px,py,on,ep,pc,cc, xc-w,y0,xc+w,y1) } 48func hbar(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, x1: i64, yc: i64, w: i64) -> i64 { return rectw(px,py,on,ep,pc,cc, x0,yc-w,x1,yc+w) } 49func seg(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, y0: i64, x1: i64, y1: i64, w: i64) -> i64 { 50 let dx: i64=x1-x0; let dy: i64=y1-y0 51 var ln: i64=isqrt(dx*dx+dy*dy); if ln==0 { ln=1 } 52 let ox: i64=w*dy/ln; let oy: i64=w*dx/ln 53 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 54 let area: i64 = ax*by-bx*ay + bx*cy-cx*by + cx*ey-ex*cy + ex*ay-ax*ey 55 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 } 56 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 } 57 on[pc]=1; on[pc+1]=1; on[pc+2]=1; on[pc+3]=1; ep[cc]=pc+3; return pc+4 58} 59 60// glyphs: 0 notdef, 1 space, 2 N, 3 I, 4 S, 5 H. wr=stem/diagonal weight, wh=horizontal weight. 61func gen_glyph(gid: i64, wr: i64, wh: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 62 if gid==0 { rectw(px,py,on,ep,0,0, 80,0,520,700); meta[0]=1; meta[1]=4; return 0 } 63 if gid==1 { meta[0]=0; meta[1]=0; return 0 } 64 var pc: i64=0 65 if gid==2 { pc=vbar(px,py,on,ep,pc,0, 115,0,700,wr); pc=vbar(px,py,on,ep,pc,1, 505,0,700,wr); pc=seg(px,py,on,ep,pc,2, 125,690,495,10,wr); meta[0]=3; meta[1]=12; return 0 } 66 if gid==3 { pc=vbar(px,py,on,ep,pc,0, 310,0,700,wr); pc=hbar(px,py,on,ep,pc,1, 210,410,680,wh); pc=hbar(px,py,on,ep,pc,2, 210,410,20,wh); meta[0]=3; meta[1]=12; return 0 } 67 if gid==4 { pc=seg(px,py,on,ep,pc,0, 470,560,300,655,wr); pc=seg(px,py,on,ep,pc,1, 300,655,150,555,wr); pc=seg(px,py,on,ep,pc,2, 150,555,300,400,wr); pc=seg(px,py,on,ep,pc,3, 300,400,470,255,wr); pc=seg(px,py,on,ep,pc,4, 470,255,300,45,wr); pc=seg(px,py,on,ep,pc,5, 300,45,140,150,wr); meta[0]=6; meta[1]=24; return 0 } 68 pc=vbar(px,py,on,ep,pc,0, 115,0,700,wr); pc=vbar(px,py,on,ep,pc,1, 505,0,700,wr); pc=hbar(px,py,on,ep,pc,2, 115,505,350,wh); meta[0]=3; meta[1]=12; return 0 69} 70// STYLE post-transform: slant shear + width scale. x' = x*xw/100 + y*slant/100 71func transform(px: *i64, py: *i64, np: i64, slant: i64, xw: i64) -> i64 { 72 var i: i64=0 73 while i<np { let x: i64=px[i]; let y: i64=py[i]; px[i]= x*xw/100 + y*slant/100; i=i+1 } 74 return 0 75} 76func append_glyph(g: *u8, go: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 77 let nc: i64=meta[0]; let np: i64=meta[1] 78 if nc==0 { return go } 79 var xmin: i64=px[0]; var xmax: i64=px[0]; var ymin: i64=py[0]; var ymax: i64=py[0] 80 var i: i64=0 81 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 } 82 var o: i64=go 83 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)) 84 i=0; while i<nc { o=w16(g,o,ep[i]); i=i+1 } 85 o=w16(g,o,0) 86 i=0; while i<np { o=w8(g,o,1); i=i+1 } 87 var prev: i64=0; i=0; while i<np { o=w16(g,o,si16(px[i]-prev)); prev=px[i]; i=i+1 } 88 prev=0; i=0; while i<np { o=w16(g,o,si16(py[i]-prev)); prev=py[i]; i=i+1 } 89 if o%2 != 0 { o=w8(g,o,0) } 90 return o 91} 92func adv_base(gid: i64) -> i64 { if gid==0 { return 600 } if gid==1 { return 380 } if gid==3 { return 380 } if gid==4 { return 620 } return 680 } 93 94// build one full sfnt for the style vector into buf. return total bytes. 95func emit_ttf(buf: *u8, wr: i64, wh: i64, slant: i64, xw: i64) -> i64 { 96 let NG: i64=6 97 let ep: *i64=sys_mmap(128) as *i64 98 let px: *i64=sys_mmap(512) as *i64 99 let py: *i64=sys_mmap(512) as *i64 100 let on: *i64=sys_mmap(512) as *i64 101 let meta: *i64=sys_mmap(16) as *i64 102 let g: *u8=sys_mmap(MAGIC_MAGIC_8192) 103 let goff: *i64=sys_mmap(64) as *i64 104 var go: i64=0 105 var q: i64=0 106 while q<NG { goff[q]=go; gen_glyph(q,wr,wh,ep,px,py,on,meta); transform(px,py,meta[1],slant,xw); go=append_glyph(g,go,ep,px,py,on,meta); q=q+1 } 107 goff[NG]=go 108 let glyf_len: i64=go 109 110 let cp: *i64=sys_mmap(64) as *i64 111 let gd: *i64=sys_mmap(64) as *i64 112 cp[0]=32; gd[0]=1 113 cp[1]=72; gd[1]=5 114 cp[2]=73; gd[2]=3 115 cp[3]=78; gd[3]=2 116 cp[4]=83; gd[4]=4 117 let NCP: i64=5 118 119 let toff: *i64=sys_mmap(128) as *i64 120 let tlen: *i64=sys_mmap(128) as *i64 121 let tcs: *i64=sys_mmap(128) as *i64 122 let NT: i64=10 123 var o: i64=12 + 16*NT 124 125 o=align4(o); toff[0]=o 126 o=w16(buf,o,4); o=w16(buf,o,si16(560)); o=w16(buf,o,400); o=w16(buf,o,5); o=w16(buf,o,0) 127 o=w16(buf,o,si16(650));o=w16(buf,o,si16(700));o=w16(buf,o,si16(0));o=w16(buf,o,si16(140)) 128 o=w16(buf,o,si16(650));o=w16(buf,o,si16(700));o=w16(buf,o,si16(0));o=w16(buf,o,si16(480)) 129 o=w16(buf,o,si16(50));o=w16(buf,o,si16(260)); o=w16(buf,o,si16(0)) 130 var pi: i64=0; while pi<10 { o=w8(buf,o,0); pi=pi+1 } 131 o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0) 132 o=w8(buf,o,78);o=w8(buf,o,73);o=w8(buf,o,83);o=w8(buf,o,72) 133 o=w16(buf,o,64); o=w16(buf,o,32); o=w16(buf,o,83) 134 o=w16(buf,o,si16(800));o=w16(buf,o,si16(-200));o=w16(buf,o,si16(0)) 135 o=w16(buf,o,800);o=w16(buf,o,200) 136 o=w32(buf,o,0);o=w32(buf,o,0) 137 o=w16(buf,o,si16(480));o=w16(buf,o,si16(700)); o=w16(buf,o,0);o=w16(buf,o,32);o=w16(buf,o,1) 138 tlen[0]=o-toff[0]; o=align4(o); tcs[0]=csum(buf,toff[0],o-toff[0]) 139 140 o=align4(o); toff[1]=o 141 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) 142 let sub0: i64=o 143 let segCount: i64=NCP+1 144 o=w16(buf,o,4) 145 let lenpos: i64=o; o=w16(buf,o,0) 146 o=w16(buf,o,0) 147 o=w16(buf,o,segCount*2) 148 var p2: i64=1; while p2*2<=segCount { p2=p2*2 } 149 o=w16(buf,o,p2*2) 150 var es: i64=0; var tp: i64=p2; while tp>1 { tp=tp/2; es=es+1 } 151 o=w16(buf,o,es) 152 o=w16(buf,o,segCount*2 - p2*2) 153 var ci: i64=0; while ci<NCP { o=w16(buf,o,cp[ci]); ci=ci+1 } 154 o=w16(buf,o,MAGIC_MAGIC_65535) 155 o=w16(buf,o,0) 156 ci=0; while ci<NCP { o=w16(buf,o,cp[ci]); ci=ci+1 } 157 o=w16(buf,o,MAGIC_MAGIC_65535) 158 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 } 159 o=w16(buf,o,1) 160 ci=0; while ci<segCount { o=w16(buf,o,0); ci=ci+1 } 161 w16(buf, lenpos, o - sub0) 162 tlen[1]=o-toff[1]; o=align4(o); tcs[1]=csum(buf,toff[1],o-toff[1]) 163 164 o=align4(o); toff[2]=o 165 var gj: i64=0; while gj<glyf_len { buf[o]=g[gj]; o=o+1; gj=gj+1 } 166 tlen[2]=o-toff[2]; o=align4(o); tcs[2]=csum(buf,toff[2],o-toff[2]) 167 168 o=align4(o); toff[3]=o 169 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) 170 o=w16(buf,o,11); o=w16(buf,o,1000) 171 o=w32(buf,o,0);o=w32(buf,o,0); o=w32(buf,o,0);o=w32(buf,o,0) 172 o=w16(buf,o,si16(-50));o=w16(buf,o,si16(0));o=w16(buf,o,MAGIC_MAGIC_1100);o=w16(buf,o,720) 173 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) 174 tlen[3]=o-toff[3]; o=align4(o); tcs[3]=csum(buf,toff[3],o-toff[3]) 175 176 o=align4(o); toff[4]=o 177 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)) 178 o=w16(buf,o,MAGIC_MAGIC_1100); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(MAGIC_MAGIC_1100)) 179 o=w16(buf,o,si16(1)); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(0)) 180 o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0) 181 o=w16(buf,o,si16(0)); o=w16(buf,o,NG) 182 tlen[4]=o-toff[4]; o=align4(o); tcs[4]=csum(buf,toff[4],o-toff[4]) 183 184 o=align4(o); toff[5]=o 185 var hi: i64=0; while hi<NG { o=w16(buf,o,adv_base(hi)*xw/100); o=w16(buf,o,si16(30)); hi=hi+1 } 186 tlen[5]=o-toff[5]; o=align4(o); tcs[5]=csum(buf,toff[5],o-toff[5]) 187 188 o=align4(o); toff[6]=o 189 var li: i64=0; while li<NG+1 { o=w16(buf,o,goff[li]/2); li=li+1 } 190 tlen[6]=o-toff[6]; o=align4(o); tcs[6]=csum(buf,toff[6],o-toff[6]) 191 192 o=align4(o); toff[7]=o 193 o=w32(buf,o,MAGIC_MAGIC_65536); o=w16(buf,o,NG); o=w16(buf,o,24); o=w16(buf,o,6) 194 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) 195 tlen[7]=o-toff[7]; o=align4(o); tcs[7]=csum(buf,toff[7],o-toff[7]) 196 197 o=align4(o); toff[8]=o 198 o=w16(buf,o,0); o=w16(buf,o,1); o=w16(buf,o,18) 199 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,10);o=w16(buf,o,0) 200 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) 201 tlen[8]=o-toff[8]; o=align4(o); tcs[8]=csum(buf,toff[8],o-toff[8]) 202 203 o=align4(o); toff[9]=o 204 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) 205 tlen[9]=o-toff[9]; o=align4(o); tcs[9]=csum(buf,toff[9],o-toff[9]) 206 207 let total: i64=o 208 var hh: i64=0 209 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) 210 let tags: *u8="OS/2cmapglyfheadhheahmtxlocamaxpnamepost" as *u8 211 var d: i64=12; var ti: i64=0 212 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] 213 w32(buf,d+4,tcs[ti]); w32(buf,d+8,toff[ti]); w32(buf,d+12,tlen[ti]); d=d+16; ti=ti+1 } 214 let fsum0: i64=csum(buf,0,total) 215 var adj: i64=MAGIC_ADJ - fsum0 216 if adj<0 { adj=adj+MAGIC_MAGIC_4294967296 } 217 w32(buf, toff[3]+8, adj) 218 return total 219} 220 221func main() -> i64 { 222 // STYLE VECTORS: {wr, wh, slant, xw} -- change a row -> a new distinct font 223 let SV: *i64=sys_mmap(256) as *i64 224 SV[0]=42; SV[1]=28; SV[2]=0; SV[3]=100 // Regular 225 SV[4]=42; SV[5]=28; SV[6]=22; SV[7]=100 // Oblique (slant) 226 SV[8]=48; SV[9]=32; SV[10]=0; SV[11]=66 // Condensed (narrow) 227 SV[12]=74; SV[13]=56; SV[14]=0; SV[15]=110 // Bold + wide 228 SV[16]=28; SV[17]=20; SV[18]=0; SV[19]=138 // Wide Light 229 let NVAR: i64=5 230 231 let b64: *u8=sys_mmap(MAGIC_MAGIC_65536) 232 let pg: *u8=sys_mmap(MAGIC_MAGIC_262144) 233 var po: i64=0 234 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 &mdash; one definition, many variants</title><style>" as *u8) 235 236 let names: *u8="RegularObliqueCondensBold-Wd Wide-Lt" as *u8 // 7-char labels 237 var v: i64=0 238 while v<NVAR { 239 let buf: *u8=sys_mmap(MAGIC_MAGIC_16384) 240 let total: i64=emit_ttf(buf, SV[v*4], SV[v*4+1], SV[v*4+2], SV[v*4+3]) 241 var path: *u8="web_assets/nishi_var_0.ttf" as *u8 242 if v==0 { path="web_assets/nishi_var_0.ttf" as *u8 } 243 if v==1 { path="web_assets/nishi_var_1.ttf" as *u8 } 244 if v==2 { path="web_assets/nishi_var_2.ttf" as *u8 } 245 if v==3 { path="web_assets/nishi_var_3.ttf" as *u8 } 246 if v==4 { path="web_assets/nishi_var_4.ttf" as *u8 } 247 let fd: i64=sys_openat_wr(path, 420) 248 if fd<0 { sw("SAVE-FAIL\n" as *u8); return 6 } 249 sys_write(fd, buf, total); sys_close(fd) 250 let fs: i64=csum(buf,0,total) 251 sw(" variant " as *u8); sn(v); sw(": wr=" as *u8); sn(SV[v*4]); sw(" wh=" as *u8); sn(SV[v*4+1]); sw(" slant=" as *u8); sn(SV[v*4+2]); sw(" width=" as *u8); sn(SV[v*4+3]); sw("% -> " as *u8); sw(path); sw(" self-check=" as *u8) 252 if fs==MAGIC_ADJ { sw("PASS\n" as *u8) } else { sw("FAIL\n" as *u8) } 253 b64_encode(buf, total, b64) 254 po=he_puts(pg,po,"@font-face{font-family:'NV" as *u8); po=he_puts(pg,po,path); po=he_puts(pg,po,"';src:url(data:font/ttf;base64," as *u8); po=he_puts(pg,po,b64); po=he_puts(pg,po,") format('truetype')}" as *u8) 255 v=v+1 256 } 257 po=he_puts(pg,po,"*{box-sizing:border-box}body{margin:0;min-height:100vh;background:radial-gradient(1200px 600px at 50% -10%,#161326,#0A0A0F);color:#F5F5FA;font-family:ui-sans-serif,system-ui,sans-serif;display:grid;place-items:center}.wrap{text-align:center;padding:40px}.tag{display:inline-block;font-size:.8rem;letter-spacing:.2em;text-transform:uppercase;color:#9EA0B8;margin-bottom:22px}.rowline{display:flex;align-items:baseline;gap:28px;justify-content:center;margin:14px 0}.lab{width:150px;text-align:right;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:#7B7EA0}.word{font-size:clamp(2.4rem,9vw,5.5rem);line-height:1.1;letter-spacing:.06em;background:linear-gradient(100deg,#8A7BFF,#FF7A59);-webkit-background-clip:text;background-clip:text;color:transparent}.v0{font-family:'NVweb_assets/nishi_var_0.ttf'}.v1{font-family:'NVweb_assets/nishi_var_1.ttf'}.v2{font-family:'NVweb_assets/nishi_var_2.ttf'}.v3{font-family:'NVweb_assets/nishi_var_3.ttf'}.v4{font-family:'NVweb_assets/nishi_var_4.ttf'}.note{color:#9EA0B8;max-width:56ch;margin:34px auto 0;font-size:1.02rem;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) 258 po=he_puts(pg,po,"<span class=\"tag\">&#9733; one glyph definition &middot; one style vector &middot; many fonts</span>" as *u8) 259 po=he_puts(pg,po,"<div class=\"rowline\"><div class=\"lab\">Regular</div><div class=\"word v0\">NISHI</div></div>" as *u8) 260 po=he_puts(pg,po,"<div class=\"rowline\"><div class=\"lab\">Oblique</div><div class=\"word v1\">NISHI</div></div>" as *u8) 261 po=he_puts(pg,po,"<div class=\"rowline\"><div class=\"lab\">Condensed</div><div class=\"word v2\">NISHI</div></div>" as *u8) 262 po=he_puts(pg,po,"<div class=\"rowline\"><div class=\"lab\">Bold Wide</div><div class=\"word v3\">NISHI</div></div>" as *u8) 263 po=he_puts(pg,po,"<div class=\"rowline\"><div class=\"lab\">Wide Light</div><div class=\"word v4\">NISHI</div></div>" as *u8) 264 po=he_puts(pg,po,"<p class=\"note\">Every row is the <b>same glyph definition</b> through a different <b>style vector</b> <span class=\"mono\">{stem, contrast, slant, width}</span>. If a variant reads too close to another font, change the vector and regenerate a distinct, drop-in replacement &mdash; no re-drawing, each a real self-validated <span class=\"mono\">.ttf</span>. This is the sovereign advantage: fonts are <b>generated</b>, so variation and replacement are a parameter change.</p>" as *u8) 265 po=he_puts(pg,po,"</div></body></html>" as *u8) 266 let pfd: i64=sys_openat_wr("web_assets/nishi_variants.html" as *u8, 420) 267 if pfd<0 { sw("PAGE-FAIL\n" as *u8); return 7 } 268 sys_write(pfd, pg, po); sys_close(pfd) 269 sw("nx_font_variants: 5 distinct variants from ONE definition -> web_assets/nishi_variants.html\n" as *u8) 270 return 0 271}