fromTvgFile
the returned []PMA inside PMAImage is allocated with alloc the render_alloc is used for temporary allocations in the render process
Parameters
- dbg_name:[]const u8
- []const u8
- alloc:std.mem.Allocator
- std.mem.Allocator
- render_alloc:std.mem.Allocator
- std.mem.Allocator
- tvg_bytes:[]const u8
- []const u8
- height:u32
- u32
- icon_opts:dvui.IconRenderOptions
- dvui.IconRenderOptions
Source
Implementation
pub fn fromTvgFile(dbg_name: []const u8, alloc: std.mem.Allocator, render_alloc: std.mem.Allocator, tvg_bytes: []const u8, height: u32, icon_opts: dvui.IconRenderOptions) !PMAImage {
if (comptime !dvui.useTvg) {
comptime unreachable;
}
const ImageAdapter = struct {
pixels: []u8,
width: u32,
height: u32,
pub fn setPixel(self: *@This(), x: usize, y: usize, col: [4]u8) void {
const idx = (y * self.width + x) * 4;
for (0..4) |i| self.pixels[idx + i] = col[i];
}
pub fn getPixel(self: *@This(), x: usize, y: usize) [4]u8 {
const idx = y * self.width + x;
const slice = self.pixels[idx * 4 .. (idx + 1) * 4];
var col: [4]u8 = undefined;
for (&col, slice) |*a, s| a.* = s;
}
fn conv(dcol: dvui.Color) tvg.Color {
return tvg.Color{
.r = @as(f32, dcol.r) / 255.0,
.g = @as(f32, dcol.g) / 255.0,
.b = @as(f32, dcol.b) / 255.0,
.a = @as(f32, dcol.a) / 255.0,
};
}
};
var width: u32 = @trunc(try dvui.iconWidth(dbg_name, tvg_bytes, @floatFromInt(height)));
// height will be at least 1, but iconWidth could return < 1, truncated
// to 0, which would fail rendering
width = @max(width, 1);
const img_raw_data = try alloc.alloc(u8, width * height * 4);
@memset(img_raw_data, 0);
var img = ImageAdapter{
.pixels = img_raw_data,
.width = width,
.height = height,
};
var fb: std.Io.Reader = .fixed(tvg_bytes);
var ow_stroke: ?tvg.Color = null;
if (icon_opts.stroke_color) |cx| ow_stroke = ImageAdapter.conv(cx);
var ow_fill: ?tvg.Color = null;
var disable_fill = false;
if (ow_fill != null and ow_fill.?.a == 0.0) disable_fill = true;
if (icon_opts.fill_color) |cx| ow_fill = ImageAdapter.conv(cx);
tvg.renderStream(dvui.io, render_alloc, &img, &fb, .{
.overwrite_stroke_width = icon_opts.stroke_width,
.overwrite_stroke = ow_stroke,
.overwrite_fill = ow_fill,
.disable_fill = disable_fill,
}) catch |err| {
dvui.log.warn("iconTexture Tinyvg error {any} rendering icon {s} at height {d}\n", .{ err, dbg_name, height });
return dvui.TvgError.tvgError;
};
return PMAImage{
.pma = std.mem.bytesAsSlice(PMA, img.pixels),
.width = img.width,
.height = img.height,
};
}