WIP: lunasvg implementation, things stopped working
This commit is contained in:
76
src/ui/ui_icons.cpp
Normal file
76
src/ui/ui_icons.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
// ui_icons.cpp - SVG icon rasterization via lunasvg
|
||||
|
||||
#include "ui/ui_icons.h"
|
||||
#include <lunasvg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
UI_IconInfo g_icons[UI_ICON_COUNT] = {};
|
||||
|
||||
// Simple SVG icon sources (24x24 viewBox)
|
||||
static const char *g_icon_svgs[UI_ICON_COUNT] = {
|
||||
// UI_ICON_CLOSE - X mark
|
||||
R"(<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M6 6 L18 18 M18 6 L6 18" stroke="white" stroke-width="2.5" stroke-linecap="round"/>
|
||||
</svg>)",
|
||||
|
||||
// UI_ICON_CHECK - checkmark
|
||||
R"(<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M5 12 L10 17 L19 7" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
</svg>)",
|
||||
|
||||
// UI_ICON_CHEVRON_DOWN - downward arrow
|
||||
R"(<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M7 10 L12 15 L17 10" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
</svg>)",
|
||||
};
|
||||
|
||||
U8 *ui_icons_rasterize_atlas(S32 *out_w, S32 *out_h, S32 icon_size) {
|
||||
// Pack icons in a row
|
||||
S32 atlas_w = icon_size * UI_ICON_COUNT;
|
||||
S32 atlas_h = icon_size;
|
||||
|
||||
// Pad to power of 2 isn't necessary for correctness, but ensure minimum size
|
||||
if (atlas_w < 64) atlas_w = 64;
|
||||
if (atlas_h < 64) atlas_h = 64;
|
||||
|
||||
U8 *atlas = (U8 *)calloc(atlas_w * atlas_h, 1);
|
||||
if (!atlas) return nullptr;
|
||||
|
||||
S32 pen_x = 0;
|
||||
for (S32 i = 0; i < UI_ICON_COUNT; i++) {
|
||||
auto doc = lunasvg::Document::loadFromData(g_icon_svgs[i]);
|
||||
if (!doc) continue;
|
||||
|
||||
lunasvg::Bitmap bmp = doc->renderToBitmap(icon_size, icon_size);
|
||||
if (bmp.isNull()) continue;
|
||||
|
||||
// Extract alpha channel from ARGB32 premultiplied into R8
|
||||
U8 *src = bmp.data();
|
||||
S32 bmp_w = bmp.width();
|
||||
S32 bmp_h = bmp.height();
|
||||
S32 stride = bmp.stride();
|
||||
|
||||
for (S32 y = 0; y < bmp_h && y < atlas_h; y++) {
|
||||
for (S32 x = 0; x < bmp_w && (pen_x + x) < atlas_w; x++) {
|
||||
// ARGB32 premultiplied: bytes are B, G, R, A (little-endian)
|
||||
U8 a = src[y * stride + x * 4 + 3];
|
||||
atlas[y * atlas_w + pen_x + x] = a;
|
||||
}
|
||||
}
|
||||
|
||||
// Store UV and pixel info
|
||||
g_icons[i].u0 = (F32)pen_x / (F32)atlas_w;
|
||||
g_icons[i].v0 = 0.0f;
|
||||
g_icons[i].u1 = (F32)(pen_x + bmp_w) / (F32)atlas_w;
|
||||
g_icons[i].v1 = (F32)bmp_h / (F32)atlas_h;
|
||||
g_icons[i].w = (F32)bmp_w;
|
||||
g_icons[i].h = (F32)bmp_h;
|
||||
|
||||
pen_x += icon_size;
|
||||
}
|
||||
|
||||
*out_w = atlas_w;
|
||||
*out_h = atlas_h;
|
||||
return atlas;
|
||||
}
|
||||
Reference in New Issue
Block a user