79 lines
2.2 KiB
Odin
79 lines
2.2 KiB
Odin
package draw_qr
|
|
|
|
import draw ".."
|
|
import "../../qrcode"
|
|
|
|
// A registered QR code texture, ready for display via draw.rectangle_texture.
|
|
QR :: struct {
|
|
texture_id: draw.Texture_Id,
|
|
size: int, // modules per side (e.g. 21..177)
|
|
}
|
|
|
|
// Encode text as a QR code and register the result as an R8 texture.
|
|
// The texture uses Nearest_Clamp sampling by default (sharp module edges).
|
|
// Returns ok=false if encoding or registration fails.
|
|
@(require_results)
|
|
create_from_text :: proc(
|
|
text: string,
|
|
ecl: qrcode.Ecc = .Low,
|
|
min_version: int = qrcode.VERSION_MIN,
|
|
max_version: int = qrcode.VERSION_MAX,
|
|
mask: Maybe(qrcode.Mask) = nil,
|
|
boost_ecl: bool = true,
|
|
) -> (
|
|
qr: QR,
|
|
ok: bool,
|
|
) {
|
|
qrcode_buf: [qrcode.BUFFER_LEN_MAX]u8
|
|
encode_ok := qrcode.encode(text, qrcode_buf[:], ecl, min_version, max_version, mask, boost_ecl)
|
|
if !encode_ok do return {}, false
|
|
return create(qrcode_buf[:])
|
|
}
|
|
|
|
// Register an already-encoded QR code buffer as an R8 texture.
|
|
// qrcode_buf must be the output of qrcode.encode (byte 0 = side length, remaining = bit-packed modules).
|
|
@(require_results)
|
|
create :: proc(qrcode_buf: []u8) -> (qr: QR, ok: bool) {
|
|
size := qrcode.get_size(qrcode_buf)
|
|
if size == 0 do return {}, false
|
|
|
|
// Build R8 pixel buffer: 0 = light, 255 = dark
|
|
pixels := make([]u8, size * size, context.temp_allocator)
|
|
for y in 0 ..< size {
|
|
for x in 0 ..< size {
|
|
pixels[y * size + x] = 255 if qrcode.get_module(qrcode_buf, x, y) else 0
|
|
}
|
|
}
|
|
|
|
id, reg_ok := draw.register_texture(
|
|
draw.Texture_Desc {
|
|
width = u32(size),
|
|
height = u32(size),
|
|
depth_or_layers = 1,
|
|
type = .D2,
|
|
format = .R8_UNORM,
|
|
usage = {.SAMPLER},
|
|
mip_levels = 1,
|
|
kind = .Static,
|
|
},
|
|
pixels,
|
|
)
|
|
if !reg_ok do return {}, false
|
|
|
|
return QR{texture_id = id, size = size}, true
|
|
}
|
|
|
|
// Release the GPU texture.
|
|
destroy :: proc(qr: ^QR) {
|
|
draw.unregister_texture(qr.texture_id)
|
|
qr.texture_id = draw.INVALID_TEXTURE
|
|
qr.size = 0
|
|
}
|
|
|
|
// Convenience: build a Clay_Image_Data for embedding a QR in Clay layouts.
|
|
// Uses Nearest_Clamp sampling (set via Sampler_Preset at draw time, not here) and Fit mode
|
|
// to preserve the QR's square aspect ratio.
|
|
clay_image :: proc(qr: QR, tint: draw.Color = draw.WHITE) -> draw.Clay_Image_Data {
|
|
return draw.clay_image_data(qr.texture_id, fit = .Fit, tint = tint)
|
|
}
|