L
ling-wallet
↓ 0 downloadsLing Wallet: a post-quantum privacy-coin wallet, full node and HyperTorus miner for LNG
Keywords wallet, cryptocurrency, lng, node, miner, ling
lingfu install ling-walletCode / Files (116)
ling/ui/qr.ling
# qr.ling — QR modules as rows of "0"/"1" strings (the lw_qr row format),
# built from the runtime's qr_svg renderer, cached per text.
fn qr_rows(text) {
bind key = "qr:" + text
if st_has(key) > 0 { return st_get(key, []) }
bind rows = qr_parse_svg(qr_svg(text))
st_set(key, rows)
return rows
}
fn svg_attr(svg, name) {
bind at = str_find(svg, name + "=\"")
if at < 0 { return 0 }
bind rest = substr(svg, at + str_len(name) + 2, 16)
return to_number(list_get(str_split(rest, "\""), 0))
}
# The svg path is a run of "M{x} {y}h{m}v{m}H{x}V{y}" squares, one per dark module.
fn qr_parse_svg(svg) {
bind size = svg_attr(svg, "width")
bind dstart = str_find(svg, " d=\"")
if dstart < 0 || size <= 0 { return [] }
bind d = list_get(str_split(substr(svg, dstart + 4, str_len(svg)), "\""), 0)
bind segs = str_split(d, "M")
bind first = list_get(segs, 1)
bind m = to_number(list_get(str_split(list_get(str_split(first, "h"), 1), "v"), 0))
if m <= 0 { return [] }
bind quiet = to_number(list_get(str_split(first, " "), 0))
bind n = round((size - 2 * quiet) / m)
bind grid = list_new()
bind i = 0
while i < n * n {
bind grid = list_push(grid, 0)
bind i = i + 1
}
bind k = 1
while k < len(segs) {
bind sg = list_get(segs, k)
bind xy = str_split(list_get(str_split(sg, "h"), 0), " ")
bind cx = round((to_number(list_get(xy, 0)) - quiet) / m)
bind cy = round((to_number(list_get(xy, 1)) - quiet) / m)
if cx >= 0 && cy >= 0 && cx < n && cy < n { bind grid = list_set(grid, cy * n + cx, 1) }
bind k = k + 1
}
bind rows = []
bind r = 0
while r < n {
bind line = ""
bind c = 0
while c < n {
bind line = line + num_str(list_get(grid, r * n + c))
bind c = c + 1
}
bind rows = list_push(rows, line)
bind r = r + 1
}
return rows
}
# Dark modules on a light plate, centred in the rect, with corner brackets.
fn qr_draw(x, y, w, h, text) {
bind rows = qr_rows(text)
bind n = len(rows)
if n == 0 { return () }
bind quiet = 3
bind m = max(1, floor(min(w, h) / (n + 2 * quiet)))
bind size = m * (n + 2 * quiet)
bind ox = x + floor((w - size) / 2)
bind oy = y + floor((h - size) / 2)
fill(ox, oy, size, size, C_QR_PLATE)
bind r = 0
while r < n {
bind line = list_get(rows, r)
bind c = 0
while c < n {
if substr(line, c, 1) == "1" {
bind run = 1
while c + run < n && substr(line, c + run, 1) == "1" { bind run = run + 1 }
fill(ox + (c + quiet) * m, oy + (r + quiet) * m, m * run, m, C_QR_DARK)
bind c = c + run
} else {
bind c = c + 1
}
}
bind r = r + 1
}
brackets(ox - 6, oy - 6, size + 12, size + 12, 16, C_BLUE, 1)
}