feat: SVG support in Image viewer app
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user