code wiki / _hdl_build / nx_brand_typescale.nx

nx_brand_typescale.nx source

↩ module page · 61 lines · 3283 B

1// nx_brand_typescale.nx -- R9 modular TYPE-SCALE generator. From a base size (milli-rem) + an integer ratio 2// (num/den, e.g. 5/4 = 1.25 "major third"), generate a modular scale of heading sizes as font tokens: 3// font|h1 = base * r^4 , font|h2 = base * r^2 , font|h3 = base * r^1 (rem) 4// NO-FLOAT (integer rational ^n, formatted to 3 decimal places). The generated scale is monotonic-descending and 5// lands inside the R2 type-scale band BY CONSTRUCTION, so bg_type_scale_ok passes. Output is a valid .brand 6// fragment (token|font|... lines) that feeds the token SSOT directly. REUSE: nx_brand_tokens (bt_app). 7// Library, no main. 100% sovereign. license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_brand_tokens.nx" 10 11func ts_ipow(base: i64, e: i64) -> i64 { var r: i64 = 1; var i: i64 = 0; while i < e { r = r * base; i = i + 1 } return r } 12// base_milli * (num/den)^n (milli-units, integer). n>=0. 13func ts_size_milli(base_milli: i64, num: i64, den: i64, n: i64) -> i64 { 14 let np: i64 = ts_ipow(num, n) 15 let dp: i64 = ts_ipow(den, n) 16 return (base_milli * np) / dp 17} 18// write a decimal integer into out at pos; return new pos. 19func ts_put_int(out: *u8, pos: i64, cap: i64, v: i64) -> i64 { 20 if v == 0 { if pos < cap { out[pos] = 48 as u8 } return pos + 1 } 21 let d: *u8 = sys_mmap(24); var m: i64 = v; var k: i64 = 0 22 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 23 var p: i64 = pos; var i: i64 = k - 1 24 while i >= 0 { if p < cap { out[p] = d[i] } p = p + 1; i = i - 1 } 25 return p 26} 27// format a milli-rem value as "<int>.<3frac>rem" into out (nul-terminated); return length. 28func ts_fmt_rem(milli: i64, out: *u8, cap: i64) -> i64 { 29 var p: i64 = ts_put_int(out, 0, cap, milli / 1000) 30 if p < cap { out[p] = 46 as u8 }; p = p + 1 // '.' 31 let fp: i64 = milli % 1000 32 if p < cap { out[p] = (48 + (fp / 100)) as u8 }; p = p + 1 33 if p < cap { out[p] = (48 + ((fp / 10) % 10)) as u8 }; p = p + 1 34 if p < cap { out[p] = (48 + (fp % 10)) as u8 }; p = p + 1 35 if p < cap { out[p] = 114 as u8 }; p = p + 1 // 'r' 36 if p < cap { out[p] = 101 as u8 }; p = p + 1 // 'e' 37 if p < cap { out[p] = 109 as u8 }; p = p + 1 // 'm' 38 if p < cap { out[p] = 0 as u8 } 39 return p 40} 41// emit one "token|font|<name>|<milli>rem\n" line at pos; return new pos. 42func ts_emit_one(out: *u8, pos: i64, cap: i64, name: *u8, milli: i64) -> i64 { 43 var q: i64 = pos 44 q = bt_app(out, q, cap, "token|font|" as *u8) 45 q = bt_app(out, q, cap, name) 46 q = bt_app(out, q, cap, "|" as *u8) 47 let rem: *u8 = sys_mmap(32) 48 ts_fmt_rem(milli, rem, 32) 49 q = bt_app(out, q, cap, rem) 50 q = bt_app(out, q, cap, "\n" as *u8) 51 return q 52} 53// generate a modular scale (.brand fragment) from base_milli + ratio num/den into out; return length. 54func ts_emit_scale(base_milli: i64, num: i64, den: i64, out: *u8, cap: i64) -> i64 { 55 var p: i64 = 0 56 p = ts_emit_one(out, p, cap, "h1" as *u8, ts_size_milli(base_milli, num, den, 4)) 57 p = ts_emit_one(out, p, cap, "h2" as *u8, ts_size_milli(base_milli, num, den, 2)) 58 p = ts_emit_one(out, p, cap, "h3" as *u8, ts_size_milli(base_milli, num, den, 1)) 59 if p < cap { out[p] = 0 as u8 } 60 return p 61}