code wiki / (root) / nx_font_full.nx

nx_font_full.nx source

↩ module page · 445 lines · 39776 B

1// nx_font_full.nx -- the COMPLETE accessible sovereign typeface: space + digits 0-9 (SLASHED zero for 0/O 2// disambiguation) + uppercase A-Z (redesigned: curved bowls, serifed I, lighter stroke) + lowercase a-z with a 3// true X-HEIGHT (the biggest readability lever). Composed from the stroke toolkit + two new curve primitives: 4// arch (n/m/h/r shoulders) and uarch (u), plus cshape/cshapeL (open C/G, digit bowls). One self-validated .ttf 5// -> web_assets/nishi_sans.ttf + page. Grounded in the legibility research (Atkinson/x-height/dyslexia). 6// 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_2048: i64 = 2048 12const MAGIC_MAGIC_131072: i64 = 131072 13const MAGIC_MAGIC_65535: i64 = 65535 14const MAGIC_MAGIC_65505: i64 = 65505 15const MAGIC_MAGIC_65490: i64 = 65490 16const MAGIC_MAGIC_65483: i64 = 65483 17const MAGIC_MAGIC_65531: i64 = 65531 18const MAGIC_MAGIC_65477: i64 = 65477 19const MAGIC_MAGIC_1594834165: i64 = 1594834165 20const MAGIC_MAGIC_1033: i64 = 1033 21const MAGIC_MAGIC_196608: i64 = 196608 22const MAGIC_MAGIC_262144: i64 = 262144 23const MAGIC_MAGIC_524288: i64 = 524288 24 25const MAGIC_ADJ: i64 = 2981146554 26const WR: i64 = 38 27const WH: i64 = 26 28 29func sw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 30func 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 } 31func si16(v: i64) -> i64 { if v<0 { return v+MAGIC_MAGIC_65536 } return v } 32func w8(b: *u8, o: i64, v: i64) -> i64 { b[o]=(v%256) as u8; return o+1 } 33func 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 } 34func 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 } 35func 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) } 36func align4(o: i64) -> i64 { while o%4 != 0 { o=o+1 } return o } 37func 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 } 38func 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 } 39func 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 } 40func b64_encode(inb: *u8, n: i64, out: *u8) -> i64 { 41 var o: i64=0; var i: i64=0 42 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 43 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 } 44 let rem: i64=n-i 45 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 } 46 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 } 47 out[o]=0 as u8; return o 48} 49func 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 } 50func add_rect(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 { 51 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 52 on[pc]=1; on[pc+1]=1; on[pc+2]=1; on[pc+3]=1; ep[cc]=pc+3; return pc+4 53} 54func 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) } 55func 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-WH,x1,yc+WH) } 56func seg(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 { 57 let dx: i64=x1-x0; let dy: i64=y1-y0 58 var ln: i64=isqrt(dx*dx+dy*dy); if ln==0 { ln=1 } 59 let ox: i64=WR*dy/ln; let oy: i64=WR*dx/ln 60 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 61 let area: i64 = ax*by-bx*ay + bx*cy-cx*by + cx*ey-ex*cy + ex*ay-ax*ey 62 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 } 63 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 } 64 on[pc]=1; on[pc+1]=1; on[pc+2]=1; on[pc+3]=1; ep[cc]=pc+3; return pc+4 65} 66func ellipse(px: *i64, py: *i64, on: *i64, ep: *i64, pc: i64, cc: i64, cx: i64, cy: i64, rx: i64, ry: i64, ccw: i64) -> i64 { 67 px[pc]=cx+rx; py[pc]=cy; on[pc]=1 68 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 } 69 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 } 70 ep[cc]=pc+7; return pc+8 71} 72func 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 { 73 px[pc]=cx; py[pc]=cy+ory; on[pc]=1; px[pc+1]=cx-orx; py[pc+1]=cy+ory; on[pc+1]=0; px[pc+2]=cx-orx; py[pc+2]=cy; on[pc+2]=1; px[pc+3]=cx-orx; py[pc+3]=cy-ory; on[pc+3]=0; 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; px[pc+6]=cx-irx; py[pc+6]=cy-iry; on[pc+6]=0; px[pc+7]=cx-irx; py[pc+7]=cy; on[pc+7]=1; px[pc+8]=cx-irx; py[pc+8]=cy+iry; on[pc+8]=0; px[pc+9]=cx; py[pc+9]=cy+iry; on[pc+9]=1 75 ep[cc]=pc+9; return pc+10 76} 77func cshapeL(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 { 78 px[pc]=cx; py[pc]=cy+ory; on[pc]=1; px[pc+1]=cx+orx; py[pc+1]=cy+ory; on[pc+1]=0; px[pc+2]=cx+orx; py[pc+2]=cy; on[pc+2]=1; px[pc+3]=cx+orx; py[pc+3]=cy-ory; on[pc+3]=0; px[pc+4]=cx; py[pc+4]=cy-ory; on[pc+4]=1 79 px[pc+5]=cx; py[pc+5]=cy-iry; on[pc+5]=1; px[pc+6]=cx+irx; py[pc+6]=cy-iry; on[pc+6]=0; px[pc+7]=cx+irx; py[pc+7]=cy; on[pc+7]=1; px[pc+8]=cx+irx; py[pc+8]=cy+iry; on[pc+8]=0; px[pc+9]=cx; py[pc+9]=cy+iry; on[pc+9]=1 80 ep[cc]=pc+9; return pc+10 81} 82// arch: solid on top (curve over), for n/m/h/r shoulders 83func arch(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 { 84 px[pc]=cx-orx; py[pc]=cy; on[pc]=1; px[pc+1]=cx-orx; py[pc+1]=cy+ory; on[pc+1]=0; px[pc+2]=cx; py[pc+2]=cy+ory; on[pc+2]=1; px[pc+3]=cx+orx; py[pc+3]=cy+ory; on[pc+3]=0; px[pc+4]=cx+orx; py[pc+4]=cy; on[pc+4]=1 85 px[pc+5]=cx+irx; py[pc+5]=cy; on[pc+5]=1; px[pc+6]=cx+irx; py[pc+6]=cy+iry; on[pc+6]=0; px[pc+7]=cx; py[pc+7]=cy+iry; on[pc+7]=1; px[pc+8]=cx-irx; py[pc+8]=cy+iry; on[pc+8]=0; px[pc+9]=cx-irx; py[pc+9]=cy; on[pc+9]=1 86 ep[cc]=pc+9; return pc+10 87} 88// uarch: solid on bottom (curve under), for u 89func uarch(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 { 90 px[pc]=cx-orx; py[pc]=cy; on[pc]=1; px[pc+1]=cx-orx; py[pc+1]=cy-ory; on[pc+1]=0; px[pc+2]=cx; py[pc+2]=cy-ory; on[pc+2]=1; px[pc+3]=cx+orx; py[pc+3]=cy-ory; on[pc+3]=0; px[pc+4]=cx+orx; py[pc+4]=cy; on[pc+4]=1 91 px[pc+5]=cx+irx; py[pc+5]=cy; on[pc+5]=1; px[pc+6]=cx+irx; py[pc+6]=cy-iry; on[pc+6]=0; px[pc+7]=cx; py[pc+7]=cy-iry; on[pc+7]=1; px[pc+8]=cx-irx; py[pc+8]=cy-iry; on[pc+8]=0; px[pc+9]=cx-irx; py[pc+9]=cy; on[pc+9]=1 92 ep[cc]=pc+9; return pc+10 93} 94 95// DIGITS 0-9 (d=0..9). Slashed 0. 96func gen_digit(d: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 97 var pc: i64=0 98 if d==0 { pc=ellipse(px,py,on,ep,pc,0, 300,350,215,350,1); pc=ellipse(px,py,on,ep,pc,1, 300,350,215-2*WR,350-2*WR,0); pc=seg(px,py,on,ep,pc,2, 185,175,415,530); meta[0]=3; meta[1]=20; return 0 } 99 if d==1 { pc=vbar(px,py,on,ep,pc,0, 300,0,700); pc=seg(px,py,on,ep,pc,1, 175,560,300,700); pc=hbar(px,py,on,ep,pc,2, 155,445,15); meta[0]=3; meta[1]=12; return 0 } 100 if d==2 { pc=cshapeL(px,py,on,ep,pc,0, 300,510,180,175,180-2*WR,175-2*WR); pc=seg(px,py,on,ep,pc,1, 455,330,150,45); pc=hbar(px,py,on,ep,pc,2, 120,480,20); meta[0]=3; meta[1]=18; return 0 } 101 if d==3 { pc=cshapeL(px,py,on,ep,pc,0, 300,515,175,170,175-2*WR,170-2*WR); pc=cshapeL(px,py,on,ep,pc,1, 300,185,190,180,190-2*WR,180-2*WR); meta[0]=2; meta[1]=20; return 0 } 102 if d==4 { pc=seg(px,py,on,ep,pc,0, 410,700,90,255); pc=hbar(px,py,on,ep,pc,1, 90,500,255); pc=vbar(px,py,on,ep,pc,2, 410,0,700); meta[0]=3; meta[1]=12; return 0 } 103 if d==5 { pc=hbar(px,py,on,ep,pc,0, 140,485,685); pc=vbar(px,py,on,ep,pc,1, 140,345,685); pc=cshapeL(px,py,on,ep,pc,2, 285,180,185,180,185-2*WR,180-2*WR); meta[0]=3; meta[1]=18; return 0 } 104 if d==6 { pc=ellipse(px,py,on,ep,pc,0, 285,185,195,185,1); pc=ellipse(px,py,on,ep,pc,1, 285,185,195-2*WR,185-2*WR,0); pc=seg(px,py,on,ep,pc,2, 160,320,400,660); meta[0]=3; meta[1]=20; return 0 } 105 if d==7 { pc=hbar(px,py,on,ep,pc,0, 90,510,685); pc=seg(px,py,on,ep,pc,1, 490,660,235,20); meta[0]=2; meta[1]=8; return 0 } 106 if d==8 { pc=ellipse(px,py,on,ep,pc,0, 300,515,175,170,1); pc=ellipse(px,py,on,ep,pc,1, 300,515,175-2*WR,170-2*WR,0); pc=ellipse(px,py,on,ep,pc,2, 300,175,195,180,1); pc=ellipse(px,py,on,ep,pc,3, 300,175,195-2*WR,180-2*WR,0); meta[0]=4; meta[1]=32; return 0 } 107 pc=ellipse(px,py,on,ep,pc,0, 315,510,190,185,1); pc=ellipse(px,py,on,ep,pc,1, 315,510,190-2*WR,185-2*WR,0); pc=vbar(px,py,on,ep,pc,2, 430,15,510); meta[0]=3; meta[1]=20; return 0 108} 109 110// UPPERCASE A-Z (L=0..25), redesigned (curved bowls, serifed I) 111func gen_upper(L: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 112 var pc: i64=0 113 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 } 114 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 } 115 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 } 116 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 } 117 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 } 118 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 } 119 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 } 120 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 } 121 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 } 122 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 } 123 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 } 124 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 } 125 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 } 126 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 } 127 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 } 128 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 } 129 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 } 130 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 } 131 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 } 132 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 } 133 if L==20 { pc=vbar(px,py,on,ep,pc,0, 115,180,700); pc=vbar(px,py,on,ep,pc,1, 505,180,700); pc=uarch(px,py,on,ep,pc,2, 310,180,195,180,195-2*WR,180-2*WR); meta[0]=3; meta[1]=18; return 0 } 134 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 } 135 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 } 136 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 } 137 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 } 138 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 139} 140 141// LOWERCASE a-z (c=0..25), true x-height (XH=480), asc 700, desc -190 142func gen_lower(c: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 143 var pc: i64=0 144 if c==0 { pc=ellipse(px,py,on,ep,pc,0, 215,150,185,150,1); pc=ellipse(px,py,on,ep,pc,1, 215,150,185-2*WR,150-2*WR,0); pc=vbar(px,py,on,ep,pc,2, 385,0,470); pc=seg(px,py,on,ep,pc,3, 160,450,385,420); meta[0]=4; meta[1]=24; return 0 } 145 if c==1 { pc=vbar(px,py,on,ep,pc,0, 130,0,700); pc=ellipse(px,py,on,ep,pc,1, 305,150,175,150,1); pc=ellipse(px,py,on,ep,pc,2, 305,150,175-2*WR,150-2*WR,0); meta[0]=3; meta[1]=20; return 0 } 146 if c==2 { pc=cshape(px,py,on,ep,pc,0, 280,235,205,245,205-2*WR,245-2*WR); meta[0]=1; meta[1]=10; return 0 } 147 if c==3 { pc=ellipse(px,py,on,ep,pc,0, 255,150,175,150,1); pc=ellipse(px,py,on,ep,pc,1, 255,150,175-2*WR,150-2*WR,0); pc=vbar(px,py,on,ep,pc,2, 430,0,700); meta[0]=3; meta[1]=20; return 0 } 148 if c==4 { pc=cshape(px,py,on,ep,pc,0, 270,235,205,245,205-2*WR,245-2*WR); pc=hbar(px,py,on,ep,pc,1, 70,415,235); meta[0]=2; meta[1]=14; return 0 } 149 if c==5 { pc=vbar(px,py,on,ep,pc,0, 275,0,600); pc=hbar(px,py,on,ep,pc,1, 140,410,470); pc=seg(px,py,on,ep,pc,2, 275,600,430,660); meta[0]=3; meta[1]=12; return 0 } 150 if c==6 { pc=ellipse(px,py,on,ep,pc,0, 235,255,190,175,1); pc=ellipse(px,py,on,ep,pc,1, 235,255,190-2*WR,175-2*WR,0); pc=vbar(px,py,on,ep,pc,2, 415,0-140,430); pc=seg(px,py,on,ep,pc,3, 415,0-140,180,0-110); meta[0]=4; meta[1]=24; return 0 } 151 if c==7 { pc=vbar(px,py,on,ep,pc,0, 130,0,700); pc=vbar(px,py,on,ep,pc,1, 455,0,350); pc=arch(px,py,on,ep,pc,2, 292,350,162,150,162-2*WR,150-2*WR); meta[0]=3; meta[1]=18; return 0 } 152 if c==8 { pc=vbar(px,py,on,ep,pc,0, 300,0,480); pc=ellipse(px,py,on,ep,pc,1, 300,600,60,60,1); meta[0]=2; meta[1]=12; return 0 } 153 if c==9 { pc=vbar(px,py,on,ep,pc,0, 330,0-120,480); pc=ellipse(px,py,on,ep,pc,1, 330,600,60,60,1); pc=seg(px,py,on,ep,pc,2, 330,0-120,190,0-90); meta[0]=3; meta[1]=16; return 0 } 154 if c==10 { pc=vbar(px,py,on,ep,pc,0, 130,0,700); pc=seg(px,py,on,ep,pc,1, 130,235,420,480); pc=seg(px,py,on,ep,pc,2, 130,215,420,0); meta[0]=3; meta[1]=12; return 0 } 155 if c==11 { pc=vbar(px,py,on,ep,pc,0, 285,0,700); pc=seg(px,py,on,ep,pc,1, 285,25,400,80); meta[0]=2; meta[1]=8; return 0 } 156 if c==12 { pc=vbar(px,py,on,ep,pc,0, 90,0,480); pc=vbar(px,py,on,ep,pc,1, 370,0,350); pc=vbar(px,py,on,ep,pc,2, 650,0,350); pc=arch(px,py,on,ep,pc,3, 230,350,140,150,140-2*WR,150-2*WR); pc=arch(px,py,on,ep,pc,4, 510,350,140,150,140-2*WR,150-2*WR); meta[0]=5; meta[1]=32; return 0 } 157 if c==13 { pc=vbar(px,py,on,ep,pc,0, 130,0,480); pc=vbar(px,py,on,ep,pc,1, 450,0,350); pc=arch(px,py,on,ep,pc,2, 290,350,160,150,160-2*WR,150-2*WR); meta[0]=3; meta[1]=18; return 0 } 158 if c==14 { pc=ellipse(px,py,on,ep,pc,0, 235,235,205,245,1); pc=ellipse(px,py,on,ep,pc,1, 235,235,205-2*WR,245-2*WR,0); meta[0]=2; meta[1]=16; return 0 } 159 if c==15 { pc=vbar(px,py,on,ep,pc,0, 130,0-190,480); pc=ellipse(px,py,on,ep,pc,1, 305,290,175,150,1); pc=ellipse(px,py,on,ep,pc,2, 305,290,175-2*WR,150-2*WR,0); meta[0]=3; meta[1]=20; return 0 } 160 if c==16 { pc=ellipse(px,py,on,ep,pc,0, 250,290,175,150,1); pc=ellipse(px,py,on,ep,pc,1, 250,290,175-2*WR,150-2*WR,0); pc=vbar(px,py,on,ep,pc,2, 425,0-190,480); pc=seg(px,py,on,ep,pc,3, 425,0-150,520,0-90); meta[0]=4; meta[1]=24; return 0 } 161 if c==17 { pc=vbar(px,py,on,ep,pc,0, 130,0,480); pc=seg(px,py,on,ep,pc,1, 130,410,320,470); pc=vbar(px,py,on,ep,pc,2, 320,400,470); meta[0]=3; meta[1]=12; return 0 } 162 if c==18 { pc=seg(px,py,on,ep,pc,0, 355,375,235,440); pc=seg(px,py,on,ep,pc,1, 235,440,130,385); pc=seg(px,py,on,ep,pc,2, 130,385,235,240); pc=seg(px,py,on,ep,pc,3, 235,240,340,120); pc=seg(px,py,on,ep,pc,4, 340,120,235,35); pc=seg(px,py,on,ep,pc,5, 235,35,115,95); meta[0]=6; meta[1]=24; return 0 } 163 if c==19 { pc=vbar(px,py,on,ep,pc,0, 230,0,600); pc=hbar(px,py,on,ep,pc,1, 100,390,480); pc=seg(px,py,on,ep,pc,2, 230,25,340,70); meta[0]=3; meta[1]=12; return 0 } 164 if c==20 { pc=vbar(px,py,on,ep,pc,0, 130,140,480); pc=vbar(px,py,on,ep,pc,1, 450,0,480); pc=uarch(px,py,on,ep,pc,2, 290,140,160,140,160-2*WR,140-2*WR); meta[0]=3; meta[1]=18; return 0 } 165 if c==21 { pc=seg(px,py,on,ep,pc,0, 90,480,235,0); pc=seg(px,py,on,ep,pc,1, 380,480,235,0); meta[0]=2; meta[1]=8; return 0 } 166 if c==22 { pc=seg(px,py,on,ep,pc,0, 60,480,160,0); pc=seg(px,py,on,ep,pc,1, 160,0,280,340); pc=seg(px,py,on,ep,pc,2, 280,340,400,0); pc=seg(px,py,on,ep,pc,3, 400,0,500,480); meta[0]=4; meta[1]=16; return 0 } 167 if c==23 { pc=seg(px,py,on,ep,pc,0, 90,0,420,480); pc=seg(px,py,on,ep,pc,1, 90,480,420,0); meta[0]=2; meta[1]=8; return 0 } 168 if c==24 { pc=seg(px,py,on,ep,pc,0, 90,480,255,120); pc=seg(px,py,on,ep,pc,1, 430,480,110,0-190); meta[0]=2; meta[1]=8; return 0 } 169 pc=hbar(px,py,on,ep,pc,0, 90,430,470); pc=seg(px,py,on,ep,pc,1, 420,450,120,30); pc=hbar(px,py,on,ep,pc,2, 90,430,15); meta[0]=3; meta[1]=12; return 0 170} 171 172// PUNCTUATION (full printable ASCII). gids 64-78 = chars 33-47 (! " # $ % & ' ( ) * + , - . /) 173func gen_punct1(k: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 174 var pc: i64=0 175 if k==0 { pc=vbar(px,py,on,ep,pc,0, 300,190,700); pc=add_rect(px,py,on,ep,pc,1, 258,0,342,90); meta[0]=2; meta[1]=8; return 0 } 176 if k==1 { pc=vbar(px,py,on,ep,pc,0, 225,530,700); pc=vbar(px,py,on,ep,pc,1, 375,530,700); meta[0]=2; meta[1]=8; return 0 } 177 if k==2 { pc=vbar(px,py,on,ep,pc,0, 230,80,620); pc=vbar(px,py,on,ep,pc,1, 430,80,620); pc=hbar(px,py,on,ep,pc,2, 100,560,430); pc=hbar(px,py,on,ep,pc,3, 100,560,190); meta[0]=4; meta[1]=16; return 0 } 178 if k==3 { 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); pc=vbar(px,py,on,ep,pc,6, 305,0-30,730); meta[0]=7; meta[1]=28; return 0 } 179 if k==4 { pc=ellipse(px,py,on,ep,pc,0, 160,540,105,105,1); pc=ellipse(px,py,on,ep,pc,1, 160,540,105-2*WR,105-2*WR,0); pc=ellipse(px,py,on,ep,pc,2, 440,160,105,105,1); pc=ellipse(px,py,on,ep,pc,3, 440,160,105-2*WR,105-2*WR,0); pc=seg(px,py,on,ep,pc,4, 500,650,100,50); meta[0]=5; meta[1]=36; return 0 } 180 if k==5 { pc=ellipse(px,py,on,ep,pc,0, 240,500,140,145,1); pc=ellipse(px,py,on,ep,pc,1, 240,500,140-2*WR,145-2*WR,0); pc=ellipse(px,py,on,ep,pc,2, 250,190,175,180,1); pc=ellipse(px,py,on,ep,pc,3, 250,190,175-2*WR,180-2*WR,0); pc=seg(px,py,on,ep,pc,4, 330,300,560,40); meta[0]=5; meta[1]=36; return 0 } 181 if k==6 { pc=vbar(px,py,on,ep,pc,0, 300,530,700); meta[0]=1; meta[1]=4; return 0 } 182 if k==7 { pc=cshape(px,py,on,ep,pc,0, 340,300,180,420,180-2*WR,420-2*WR); meta[0]=1; meta[1]=10; return 0 } 183 if k==8 { pc=cshapeL(px,py,on,ep,pc,0, 240,300,180,420,180-2*WR,420-2*WR); meta[0]=1; meta[1]=10; return 0 } 184 if k==9 { pc=vbar(px,py,on,ep,pc,0, 300,430,700); pc=seg(px,py,on,ep,pc,1, 170,660,430,470); pc=seg(px,py,on,ep,pc,2, 170,470,430,660); meta[0]=3; meta[1]=12; return 0 } 185 if k==10 { pc=hbar(px,py,on,ep,pc,0, 110,490,300); pc=vbar(px,py,on,ep,pc,1, 300,120,480); meta[0]=2; meta[1]=8; return 0 } 186 if k==11 { pc=add_rect(px,py,on,ep,pc,0, 258,0-10,342,100); pc=seg(px,py,on,ep,pc,1, 310,0,230,0-150); meta[0]=2; meta[1]=8; return 0 } 187 if k==12 { pc=hbar(px,py,on,ep,pc,0, 130,470,300); meta[0]=1; meta[1]=4; return 0 } 188 if k==13 { pc=add_rect(px,py,on,ep,pc,0, 258,0,342,90); meta[0]=1; meta[1]=4; return 0 } 189 pc=seg(px,py,on,ep,pc,0, 130,0-80,470,730); meta[0]=1; meta[1]=4; return 0 190} 191// gids 79-85 = chars 58-64 (: ; < = > ? @) 192func gen_punct2(k: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 193 var pc: i64=0 194 if k==0 { pc=add_rect(px,py,on,ep,pc,0, 258,0,342,90); pc=add_rect(px,py,on,ep,pc,1, 258,390,342,480); meta[0]=2; meta[1]=8; return 0 } 195 if k==1 { pc=add_rect(px,py,on,ep,pc,0, 258,390,342,480); pc=add_rect(px,py,on,ep,pc,1, 258,0-10,342,100); pc=seg(px,py,on,ep,pc,2, 310,0,230,0-150); meta[0]=3; meta[1]=12; return 0 } 196 if k==2 { pc=seg(px,py,on,ep,pc,0, 470,540,140,300); pc=seg(px,py,on,ep,pc,1, 140,300,470,60); meta[0]=2; meta[1]=8; return 0 } 197 if k==3 { pc=hbar(px,py,on,ep,pc,0, 120,480,400); pc=hbar(px,py,on,ep,pc,1, 120,480,200); meta[0]=2; meta[1]=8; return 0 } 198 if k==4 { pc=seg(px,py,on,ep,pc,0, 130,540,460,300); pc=seg(px,py,on,ep,pc,1, 460,300,130,60); meta[0]=2; meta[1]=8; return 0 } 199 if k==5 { pc=cshapeL(px,py,on,ep,pc,0, 290,530,165,170,165-2*WR,170-2*WR); pc=vbar(px,py,on,ep,pc,1, 300,190,370); pc=add_rect(px,py,on,ep,pc,2, 262,0,338,80); meta[0]=3; meta[1]=18; return 0 } 200 pc=ellipse(px,py,on,ep,pc,0, 300,250,255,275,1); pc=ellipse(px,py,on,ep,pc,1, 300,250,255-2*WR,275-2*WR,0); pc=ellipse(px,py,on,ep,pc,2, 310,250,85,95,1); meta[0]=3; meta[1]=24; return 0 201} 202// gids 86-91 = chars 91-96 ([ \ ] ^ _ `) 203func gen_punct3(k: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 204 var pc: i64=0 205 if k==0 { pc=vbar(px,py,on,ep,pc,0, 255,0-100,720); pc=hbar(px,py,on,ep,pc,1, 255,420,694); pc=hbar(px,py,on,ep,pc,2, 255,420,0-74); meta[0]=3; meta[1]=12; return 0 } 206 if k==1 { pc=seg(px,py,on,ep,pc,0, 130,730,470,0-80); meta[0]=1; meta[1]=4; return 0 } 207 if k==2 { pc=vbar(px,py,on,ep,pc,0, 345,0-100,720); pc=hbar(px,py,on,ep,pc,1, 180,345,694); pc=hbar(px,py,on,ep,pc,2, 180,345,0-74); meta[0]=3; meta[1]=12; return 0 } 208 if k==3 { pc=seg(px,py,on,ep,pc,0, 160,500,300,700); pc=seg(px,py,on,ep,pc,1, 300,700,440,500); meta[0]=2; meta[1]=8; return 0 } 209 if k==4 { pc=hbar(px,py,on,ep,pc,0, 70,530,0-120); meta[0]=1; meta[1]=4; return 0 } 210 pc=seg(px,py,on,ep,pc,0, 250,700,360,570); meta[0]=1; meta[1]=4; return 0 211} 212// gids 92-95 = chars 123-126 ({ | } ~) 213func gen_punct4(k: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 214 var pc: i64=0 215 if k==0 { pc=vbar(px,py,on,ep,pc,0, 330,0-80,700); pc=hbar(px,py,on,ep,pc,1, 330,450,674); pc=hbar(px,py,on,ep,pc,2, 330,450,0-54); pc=hbar(px,py,on,ep,pc,3, 200,330,310); meta[0]=4; meta[1]=16; return 0 } 216 if k==1 { pc=vbar(px,py,on,ep,pc,0, 300,0-100,720); meta[0]=1; meta[1]=4; return 0 } 217 if k==2 { pc=vbar(px,py,on,ep,pc,0, 270,0-80,700); pc=hbar(px,py,on,ep,pc,1, 150,270,674); pc=hbar(px,py,on,ep,pc,2, 150,270,0-54); pc=hbar(px,py,on,ep,pc,3, 270,400,310); meta[0]=4; meta[1]=16; return 0 } 218 pc=seg(px,py,on,ep,pc,0, 110,330,225,410); pc=seg(px,py,on,ep,pc,1, 225,410,375,330); pc=seg(px,py,on,ep,pc,2, 375,330,490,410); meta[0]=3; meta[1]=12; return 0 219} 220 221func gen(gid: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 222 if gid==0 { add_rect(px,py,on,ep,0,0, 80,0,520,700); meta[0]=1; meta[1]=4; return 0 } 223 if gid==1 { meta[0]=0; meta[1]=0; return 0 } 224 if gid<12 { return gen_digit(gid-2, ep,px,py,on,meta) } 225 if gid<38 { return gen_upper(gid-12, ep,px,py,on,meta) } 226 if gid<64 { return gen_lower(gid-38, ep,px,py,on,meta) } 227 if gid<79 { return gen_punct1(gid-64, ep,px,py,on,meta) } 228 if gid<86 { return gen_punct2(gid-79, ep,px,py,on,meta) } 229 if gid<92 { return gen_punct3(gid-86, ep,px,py,on,meta) } 230 return gen_punct4(gid-92, ep,px,py,on,meta) 231} 232func adv_of(gid: i64) -> i64 { 233 if gid==0 { return 600 } 234 if gid==1 { return 380 } 235 if gid<12 { return 600 } 236 if gid<38 { let L: i64=gid-12; if L==8 { return 360 } if L==12 { return 820 } if L==22 { return 840 } return 660 } 237 if gid<64 { 238 let c: i64=gid-38 239 if c==8 { return 300 } 240 if c==9 { return 320 } 241 if c==11 { return 300 } 242 if c==12 { return 800 } 243 if c==22 { return 800 } 244 return 560 245 } 246 if gid<79 { 247 let k: i64=gid-64 248 if k==0 { return 380 } 249 if k==1 { return 440 } 250 if k==6 { return 240 } 251 if k==7 { return 400 } 252 if k==8 { return 400 } 253 if k==11 { return 300 } 254 if k==13 { return 300 } 255 if k==14 { return 520 } 256 return 640 257 } 258 if gid<86 { 259 let k2: i64=gid-79 260 if k2==0 { return 300 } 261 if k2==1 { return 300 } 262 if k2==5 { return 560 } 263 if k2==6 { return 820 } 264 return 600 265 } 266 if gid<92 { 267 let k3: i64=gid-86 268 if k3==0 { return 420 } 269 if k3==2 { return 420 } 270 if k3==1 { return 520 } 271 if k3==5 { return 300 } 272 return 600 273 } 274 let k4: i64=gid-92 275 if k4==1 { return 380 } 276 if k4==3 { return 600 } 277 return 460 278} 279 280func append_glyph(g: *u8, go: i64, ep: *i64, px: *i64, py: *i64, on: *i64, meta: *i64) -> i64 { 281 let nc: i64=meta[0]; let np: i64=meta[1] 282 if nc==0 { return go } 283 var xmin: i64=px[0]; var xmax: i64=px[0]; var ymin: i64=py[0]; var ymax: i64=py[0] 284 var i: i64=0 285 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 } 286 var o: i64=go 287 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)) 288 i=0; while i<nc { o=w16(g,o,ep[i]); i=i+1 } 289 o=w16(g,o,0) 290 i=0; while i<np { if on[i]==1 { o=w8(g,o,1) } else { o=w8(g,o,0) } i=i+1 } 291 var prev: i64=0; i=0; while i<np { o=w16(g,o,si16(px[i]-prev)); prev=px[i]; i=i+1 } 292 prev=0; i=0; while i<np { o=w16(g,o,si16(py[i]-prev)); prev=py[i]; i=i+1 } 293 if o%2 != 0 { o=w8(g,o,0) } 294 return o 295} 296 297func main() -> i64 { 298 let NG: i64=96 299 let ep: *i64=sys_mmap(256) as *i64 300 let px: *i64=sys_mmap(MAGIC_MAGIC_2048) as *i64 301 let py: *i64=sys_mmap(MAGIC_MAGIC_2048) as *i64 302 let on: *i64=sys_mmap(MAGIC_MAGIC_2048) as *i64 303 let meta: *i64=sys_mmap(16) as *i64 304 let g: *u8=sys_mmap(MAGIC_MAGIC_65536) 305 let goff: *i64=sys_mmap(600) as *i64 306 var go: i64=0 307 var q: i64=0 308 while q<NG { goff[q]=go; gen(q,ep,px,py,on,meta); go=append_glyph(g,go,ep,px,py,on,meta); q=q+1 } 309 goff[NG]=go 310 let glyf_len: i64=go 311 312 let buf: *u8=sys_mmap(MAGIC_MAGIC_131072) 313 let toff: *i64=sys_mmap(128) as *i64 314 let tlen: *i64=sys_mmap(128) as *i64 315 let tcs: *i64=sys_mmap(128) as *i64 316 let NT: i64=10 317 var o: i64=12 + 16*NT 318 319 // OS/2 320 o=align4(o); toff[0]=o 321 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) 322 o=w16(buf,o,si16(650));o=w16(buf,o,si16(480));o=w16(buf,o,si16(0));o=w16(buf,o,si16(140)) 323 o=w16(buf,o,si16(650));o=w16(buf,o,si16(700));o=w16(buf,o,si16(0));o=w16(buf,o,si16(480)) 324 o=w16(buf,o,si16(50));o=w16(buf,o,si16(260)); o=w16(buf,o,si16(0)) 325 var pi: i64=0; while pi<10 { o=w8(buf,o,0); pi=pi+1 } 326 o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0);o=w32(buf,o,0) 327 o=w8(buf,o,78);o=w8(buf,o,73);o=w8(buf,o,83);o=w8(buf,o,72) 328 o=w16(buf,o,64); o=w16(buf,o,32); o=w16(buf,o,126) 329 o=w16(buf,o,si16(760));o=w16(buf,o,si16(-200));o=w16(buf,o,si16(0)) 330 o=w16(buf,o,760);o=w16(buf,o,200) 331 o=w32(buf,o,0);o=w32(buf,o,0) 332 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) 333 tlen[0]=o-toff[0]; o=align4(o); tcs[0]=csum(buf,toff[0],o-toff[0]) 334 335 // cmap format-4, 9 segments = FULL printable ASCII 32-126 336 // [32]=sp->1 [33-47]->64 [48-57]->2 [58-64]->79 [65-90]->12 [91-96]->86 [97-122]->38 [123-126]->92 [term] 337 o=align4(o); toff[1]=o 338 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) 339 let sub0: i64=o 340 o=w16(buf,o,4) 341 let lenpos: i64=o; o=w16(buf,o,0) 342 o=w16(buf,o,0); o=w16(buf,o,18); o=w16(buf,o,16); o=w16(buf,o,3); o=w16(buf,o,2) // segCountX2=18 searchRange=16 entrySel=3 rangeShift=2 343 o=w16(buf,o,32); o=w16(buf,o,47); o=w16(buf,o,57); o=w16(buf,o,64); o=w16(buf,o,90); o=w16(buf,o,96); o=w16(buf,o,122); o=w16(buf,o,126); o=w16(buf,o,MAGIC_MAGIC_65535) // endCode 344 o=w16(buf,o,0) // reservedPad 345 o=w16(buf,o,32); o=w16(buf,o,33); o=w16(buf,o,48); o=w16(buf,o,58); o=w16(buf,o,65); o=w16(buf,o,91); o=w16(buf,o,97); o=w16(buf,o,123); o=w16(buf,o,MAGIC_MAGIC_65535) // startCode 346 o=w16(buf,o,MAGIC_MAGIC_65505); o=w16(buf,o,31); o=w16(buf,o,MAGIC_MAGIC_65490); o=w16(buf,o,21); o=w16(buf,o,MAGIC_MAGIC_65483); o=w16(buf,o,MAGIC_MAGIC_65531); o=w16(buf,o,MAGIC_MAGIC_65477); o=w16(buf,o,MAGIC_MAGIC_65505); o=w16(buf,o,1) // idDelta 347 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); o=w16(buf,o,0) // idRangeOffset 348 w16(buf, lenpos, o - sub0) 349 tlen[1]=o-toff[1]; o=align4(o); tcs[1]=csum(buf,toff[1],o-toff[1]) 350 351 // glyf 352 o=align4(o); toff[2]=o 353 var gj: i64=0; while gj<glyf_len { buf[o]=g[gj]; o=o+1; gj=gj+1 } 354 tlen[2]=o-toff[2]; o=align4(o); tcs[2]=csum(buf,toff[2],o-toff[2]) 355 356 // head 357 o=align4(o); toff[3]=o 358 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) 359 o=w16(buf,o,11); o=w16(buf,o,1000) 360 o=w32(buf,o,0);o=w32(buf,o,0); o=w32(buf,o,0);o=w32(buf,o,0) 361 o=w16(buf,o,si16(0));o=w16(buf,o,si16(-200));o=w16(buf,o,850);o=w16(buf,o,720) 362 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) 363 tlen[3]=o-toff[3]; o=align4(o); tcs[3]=csum(buf,toff[3],o-toff[3]) 364 365 // hhea 366 o=align4(o); toff[4]=o 367 o=w32(buf,o,MAGIC_MAGIC_65536); o=w16(buf,o,si16(760)); o=w16(buf,o,si16(-200)); o=w16(buf,o,si16(0)) 368 o=w16(buf,o,850); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(850)) 369 o=w16(buf,o,si16(1)); o=w16(buf,o,si16(0)); o=w16(buf,o,si16(0)) 370 o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0);o=w16(buf,o,0) 371 o=w16(buf,o,si16(0)); o=w16(buf,o,NG) 372 tlen[4]=o-toff[4]; o=align4(o); tcs[4]=csum(buf,toff[4],o-toff[4]) 373 374 // hmtx (NG entries) 375 o=align4(o); toff[5]=o 376 var hi: i64=0; while hi<NG { o=w16(buf,o,adv_of(hi)); o=w16(buf,o,si16(30)); hi=hi+1 } 377 tlen[5]=o-toff[5]; o=align4(o); tcs[5]=csum(buf,toff[5],o-toff[5]) 378 379 // loca short 380 o=align4(o); toff[6]=o 381 var li: i64=0; while li<NG+1 { o=w16(buf,o,goff[li]/2); li=li+1 } 382 tlen[6]=o-toff[6]; o=align4(o); tcs[6]=csum(buf,toff[6],o-toff[6]) 383 384 // maxp 385 o=align4(o); toff[7]=o 386 o=w32(buf,o,MAGIC_MAGIC_65536); o=w16(buf,o,NG); o=w16(buf,o,40); o=w16(buf,o,8) 387 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) 388 tlen[7]=o-toff[7]; o=align4(o); tcs[7]=csum(buf,toff[7],o-toff[7]) 389 390 // name 391 o=align4(o); toff[8]=o 392 o=w16(buf,o,0); o=w16(buf,o,4); o=w16(buf,o,54) 393 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) 394 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) 395 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) 396 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) 397 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) 398 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) 399 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) 400 tlen[8]=o-toff[8]; o=align4(o); tcs[8]=csum(buf,toff[8],o-toff[8]) 401 402 // post 403 o=align4(o); toff[9]=o 404 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) 405 tlen[9]=o-toff[9]; o=align4(o); tcs[9]=csum(buf,toff[9],o-toff[9]) 406 407 let total: i64=o 408 var hh: i64=0 409 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) 410 let tags: *u8="OS/2cmapglyfheadhheahmtxlocamaxpnamepost" as *u8 411 var d: i64=12; var ti: i64=0 412 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] 413 w32(buf,d+4,tcs[ti]); w32(buf,d+8,toff[ti]); w32(buf,d+12,tlen[ti]); d=d+16; ti=ti+1 } 414 let fsum0: i64=csum(buf,0,total) 415 var adj: i64=MAGIC_ADJ - fsum0 416 if adj<0 { adj=adj+MAGIC_MAGIC_4294967296 } 417 w32(buf, toff[3]+8, adj) 418 419 let fd: i64=sys_openat_wr("web_assets/nishi_sans.ttf" as *u8, 420) 420 if fd<0 { sw("SAVE-FAIL\n" as *u8); return 6 } 421 sys_write(fd, buf, total); sys_close(fd) 422 let fs: i64=csum(buf,0,total) 423 sw("nx_font_full: 96 glyphs (FULL printable ASCII 32-126) -> web_assets/nishi_sans.ttf (" as *u8); sn(total); sw("B) self-check=" as *u8) 424 if fs==MAGIC_ADJ { sw("PASS\n" as *u8) } else { sw("FAIL\n" as *u8) } 425 426 let b64: *u8=sys_mmap(MAGIC_MAGIC_262144) 427 b64_encode(buf, total, b64) 428 let pg: *u8=sys_mmap(MAGIC_MAGIC_524288) 429 var po: i64=0 430 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 complete accessible sovereign typeface</title><style>@font-face{font-family:'Nishi Sans';src:url(data:font/ttf;base64," as *u8) 431 po=he_puts(pg,po,b64) 432 po=he_puts(pg,po,") format('truetype')}*{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;max-width:1100px}.tag{display:inline-block;font-size:.8rem;letter-spacing:.2em;text-transform:uppercase;color:#9EA0B8;margin-bottom:16px}.ns{font-family:'Nishi Sans'}.hero{font-size:clamp(3rem,12vw,7rem);line-height:1.05;letter-spacing:.02em;background:linear-gradient(100deg,#8A7BFF,#FF7A59);-webkit-background-clip:text;background-clip:text;color:transparent}.set{font-size:clamp(1.3rem,4.5vw,2.4rem);letter-spacing:.06em;color:#E7E8F5;margin-top:18px;line-height:1.5}.para{font-size:clamp(1rem,2.4vw,1.35rem);color:#C7C9E0;margin-top:22px;line-height:1.7;letter-spacing:.01em}.small{font-size:15px;color:#AEB0C8;letter-spacing:.02em;margin-top:20px;line-height:1.6}.note{color:#9EA0B8;max-width:56ch;margin:28px auto 0;font-size:1rem;line-height:1.65;font-family:ui-sans-serif,system-ui,sans-serif}.note b{color:#F5F5FA}.mono{font-family:ui-monospace,Consolas,monospace;color:#8A7BFF}</style></head><body><div class=\"wrap\">" as *u8) 433 po=he_puts(pg,po,"<span class=\"tag\">&#9733; Nishi Sans &middot; complete + accessible + sovereign</span>" as *u8) 434 po=he_puts(pg,po,"<div class=\"ns hero\">Nishi Sans</div>" as *u8) 435 po=he_puts(pg,po,"<div class=\"ns set\">ABCDEFGHIJKLMNOPQRSTUVWXYZ<br>abcdefghijklmnopqrstuvwxyz<br>0123456789</div>" as *u8) 436 po=he_puts(pg,po,"<div class=\"ns para\">The quick brown fox jumps over the lazy dog. Sphinx of black quartz, judge my vow.</div>" as *u8) 437 po=he_puts(pg,po,"<div class=\"ns small\">Legible even at small sizes for low vision &mdash; open counters, a serifed capital I, a slashed zero, and a generous x-height. Illinois lawyers quiz 0 vs O.</div>" as *u8) 438 po=he_puts(pg,po,"<p class=\"note\">Every glyph &mdash; uppercase, lowercase, digits &mdash; is generated from four sovereign stroke primitives (bar, diagonal, arch, curve) into one self-validated <span class=\"mono\">.ttf</span>, rendered by our own engine. Designed to the accessibility research: <b>slashed 0</b> (vs O), <b>serifed I</b> (vs l/1), open apertures, true x-height, lighter balanced weight. Zero external load.</p>" as *u8) 439 po=he_puts(pg,po,"</div></body></html>" as *u8) 440 let pfd: i64=sys_openat_wr("web_assets/nishi_sans.html" as *u8, 420) 441 if pfd<0 { sw("PAGE-FAIL\n" as *u8); return 7 } 442 sys_write(pfd, pg, po); sys_close(pfd) 443 sw(" -> web_assets/nishi_sans.html (open to SEE the complete accessible typeface)\n" as *u8) 444 return 0 445}