update: icons

This commit is contained in:
Lucas F. 2026-01-20 18:11:19 -03:00
parent 56dd881e44
commit 966035dccb

111
src/svg/icons.zig Normal file
View file

@ -0,0 +1,111 @@
const std = @import("std");
pub const IconSet = enum {
bootstrap,
dripicons,
hero_outline,
hero_solid,
material,
};
pub const embedded_data = std.EnumMap(IconSet, []const u8).init(.{
.bootstrap = @embedFile("bootstrap.svgs.bin"),
.dripicons = @embedFile("dripicons.svgs.bin"),
.hero_outline = @embedFile("hero_outline.svgs.bin"),
.hero_solid = @embedFile("hero_solid.svgs.bin"),
.material = @embedFile("material.svgs.bin"),
});
pub const SvgIcon = struct {
icon_map: std.StringHashMapUnmanaged([]const u8) = .{},
pub fn init(allocator: std.mem.Allocator) !SvgIcon {
var self = SvgIcon{};
// const sets = [_]IconSet{ .bootstrap, .dripicons, .hero_outline, .hero_solid, .material };
//
// inline for (sets) |set| {
// const data = embedded_data.get(set).?;
//
// try self.loadSet(allocator, set, data);
// }
//
inline for (std.meta.fields(IconSet)) |field| {
const set = @field(IconSet, field.name);
const data = embedded_data.get(set);
try self.loadSet(allocator, set, data.?);
}
return self;
}
pub fn deinit(self: *SvgIcon, allocator: std.mem.Allocator) void {
var it = self.icon_map.iterator();
while (it.next()) |entry| {
allocator.free(entry.key_ptr.*);
allocator.free(entry.value_ptr.*);
}
self.icon_map.deinit(allocator);
self.* = .{};
}
pub fn get(self: *const SvgIcon, key: []const u8) ?[]const u8 {
return self.icon_map.get(key);
}
pub fn count(self: *const SvgIcon) usize {
return self.icon_map.count();
}
fn loadSet(
self: *SvgIcon,
allocator: std.mem.Allocator,
set: IconSet,
data: []const u8,
) !void {
if (data.len < 12) return error.InvalidEmbeddedData;
var pos: usize = 0;
const magic = std.mem.readInt(u32, data[pos..][0..4], .little);
pos += 4;
if (magic != 0x53564749) return error.InvalidMagic;
const version = std.mem.readInt(u32, data[pos..][0..4], .little);
pos += 4;
if (version != 1) return error.UnsupportedVersion;
const num_entries = std.mem.readInt(u32, data[pos..][0..4], .little);
pos += 4;
const prefix = @tagName(set);
var i: u32 = 0;
while (i < num_entries) : (i += 1) {
const name_len = std.mem.readInt(u32, data[pos..][0..4], .little);
pos += 4;
if (pos + name_len > data.len) return error.CorruptedNameLength;
const name_slice = data[pos .. pos + name_len];
pos += name_len;
const svg_len = std.mem.readInt(u32, data[pos..][0..4], .little);
pos += 4;
if (pos + svg_len > data.len) return error.CorruptedSvgLength;
const svg_slice = data[pos .. pos + svg_len];
pos += svg_len;
// Monta a chave com prefixo do set
const key = try std.fmt.allocPrint(allocator, "{s}:{s}", .{ prefix, name_slice });
// Duplica o conteúdo SVG (o map assume ownership)
const value = try allocator.dupe(u8, svg_slice);
// Insere no mapa unmanaged
try self.icon_map.put(allocator, key, value);
}
}
};