feat: SVG support in Image viewer app

This commit is contained in:
2026-05-18 20:07:37 +02:00
parent 47e3bb54a5
commit 6ac9ae01b0
3 changed files with 93 additions and 1 deletions
+40
View File
@@ -1626,6 +1626,46 @@ inline SvgIcon svg_render(const char* svg_data, int svg_len, int target_w, int t
// ---------------------------------------------------------------------------
// Load SVG from VFS and render
// ---------------------------------------------------------------------------
// Extract intrinsic dimensions from an SVG document. Prefers width/height
// attributes, falls back to viewBox, then to a 256x256 default. Used by the
// image viewer to render SVGs at their natural size rather than a fixed icon
// size.
inline void svg_get_natural_size(const char* svg_data, int svg_len,
int* out_w, int* out_h) {
int w = 0, h = 0;
const char* svg_tag = svg_strstr(svg_data, svg_len, "<svg");
if (svg_tag) {
int tag_offset = (int)(svg_tag - svg_data);
int tag_end = tag_offset;
while (tag_end < svg_len && svg_data[tag_end] != '>') ++tag_end;
int tag_len = tag_end - tag_offset + 1;
char attr_buf[64];
if (svg_get_attr(svg_tag, tag_len, " width", attr_buf, sizeof(attr_buf)) > 0)
w = svg_parse_int(attr_buf);
if (svg_get_attr(svg_tag, tag_len, " height", attr_buf, sizeof(attr_buf)) > 0)
h = svg_parse_int(attr_buf);
if ((w <= 0 || h <= 0) &&
svg_get_attr(svg_tag, tag_len, " viewBox", attr_buf, sizeof(attr_buf)) > 0) {
fixed_t vbx, vby, vbw, vbh;
const char* vp = attr_buf;
int c;
c = svg_parse_fixed(vp, &vbx); vp += c; while (*vp && svg_char_is_sep(*vp)) ++vp;
c = svg_parse_fixed(vp, &vby); vp += c; while (*vp && svg_char_is_sep(*vp)) ++vp;
c = svg_parse_fixed(vp, &vbw); vp += c; while (*vp && svg_char_is_sep(*vp)) ++vp;
svg_parse_fixed(vp, &vbh);
(void)vbx; (void)vby;
if (w <= 0) w = fixed_to_int(vbw);
if (h <= 0) h = fixed_to_int(vbh);
}
}
if (w <= 0) w = 256;
if (h <= 0) h = 256;
if (out_w) *out_w = w;
if (out_h) *out_h = h;
}
inline SvgIcon svg_load(const char* vfs_path, int target_w, int target_h, Color fill_color) {
int fd = montauk::open(vfs_path);
if (fd < 0) {