mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
FEAT: Unicode support using NotoEmoji
This commit is contained in:
parent
72baf6506d
commit
7eb55f3a59
6 changed files with 135 additions and 79 deletions
9
Makefile
9
Makefile
|
|
@ -200,6 +200,15 @@ $(ISO_IMAGE): $(KERNEL_ELF) limine.conf limine-setup
|
|||
fi \
|
||||
done
|
||||
|
||||
mkdir -p $(ISO_DIR)/Library/Fonts/Emoji
|
||||
@for f in $(SRC_DIR)/fonts/Emoji/*.ttf; do \
|
||||
if [ -f "$$f" ]; then \
|
||||
basename=$$(basename "$$f"); \
|
||||
cp "$$f" $(ISO_DIR)/Library/Fonts/Emoji/; \
|
||||
echo " module_path: boot():/Library/Fonts/Emoji/$$basename" >> $(ISO_DIR)/limine.conf; \
|
||||
fi \
|
||||
done
|
||||
|
||||
@if [ -f README.md ]; then \
|
||||
cp README.md $(ISO_DIR)/; \
|
||||
echo " module_path: boot():/README.md" >> $(ISO_DIR)/limine.conf; \
|
||||
|
|
|
|||
BIN
src/fonts/Emoji/NotoEmoji-VariableFont_wght.ttf
Normal file
BIN
src/fonts/Emoji/NotoEmoji-VariableFont_wght.ttf
Normal file
Binary file not shown.
|
|
@ -371,10 +371,9 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
int cur_x = ux;
|
||||
const char *s = kernel_str;
|
||||
while (*s) {
|
||||
font_manager_render_char_scaled(font, cur_x, baseline, *s, color, font->pixel_height, put_pixel);
|
||||
char buf[2] = {*s, 0};
|
||||
cur_x += font_manager_get_string_width_scaled(font, buf, font->pixel_height);
|
||||
s++;
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
font_manager_render_char_scaled(font, cur_x, baseline, codepoint, color, font->pixel_height, put_pixel);
|
||||
cur_x += font_manager_get_codepoint_width_scaled(font, codepoint, font->pixel_height);
|
||||
}
|
||||
} else {
|
||||
draw_string(ux, uy, kernel_str, color);
|
||||
|
|
@ -387,10 +386,9 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
int cur_x = win->x + ux;
|
||||
const char *s = kernel_str;
|
||||
while (*s) {
|
||||
font_manager_render_char_scaled(font, cur_x, baseline, *s, color, font->pixel_height, put_pixel);
|
||||
char buf[2] = {*s, 0};
|
||||
cur_x += font_manager_get_string_width_scaled(font, buf, font->pixel_height);
|
||||
s++;
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
font_manager_render_char_scaled(font, cur_x, baseline, codepoint, color, font->pixel_height, put_pixel);
|
||||
cur_x += font_manager_get_codepoint_width_scaled(font, codepoint, font->pixel_height);
|
||||
}
|
||||
} else {
|
||||
draw_string(win->x + ux, win->y + uy, kernel_str, color);
|
||||
|
|
@ -471,10 +469,9 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
int cur_x = ux;
|
||||
const char *s = kernel_str;
|
||||
while (*s) {
|
||||
font_manager_render_char_scaled(font, cur_x, baseline, *s, color, scale, put_pixel);
|
||||
char buf[2] = {*s, 0};
|
||||
cur_x += font_manager_get_string_width_scaled(font, buf, scale);
|
||||
s++;
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
font_manager_render_char_scaled(font, cur_x, baseline, codepoint, color, scale, put_pixel);
|
||||
cur_x += font_manager_get_codepoint_width_scaled(font, codepoint, scale);
|
||||
}
|
||||
} else {
|
||||
draw_string_scaled(ux, uy, kernel_str, color, scale);
|
||||
|
|
@ -487,10 +484,9 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
int cur_x = win->x + ux;
|
||||
const char *s = kernel_str;
|
||||
while (*s) {
|
||||
font_manager_render_char_scaled(font, cur_x, baseline, *s, color, scale, put_pixel);
|
||||
char buf[2] = {*s, 0};
|
||||
cur_x += font_manager_get_string_width_scaled(font, buf, scale);
|
||||
s++;
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
font_manager_render_char_scaled(font, cur_x, baseline, codepoint, color, scale, put_pixel);
|
||||
cur_x += font_manager_get_codepoint_width_scaled(font, codepoint, scale);
|
||||
}
|
||||
} else {
|
||||
draw_string_scaled(win->x + ux, win->y + uy, kernel_str, color, scale);
|
||||
|
|
@ -546,11 +542,10 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
int cur_x = ux;
|
||||
const char *s = kernel_str;
|
||||
while (*s) {
|
||||
extern void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, char c, uint32_t color, float scale, float slope, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
font_manager_render_char_sloped(font, cur_x, baseline, *s, color, scale, slope, put_pixel);
|
||||
char buf[2] = {*s, 0};
|
||||
cur_x += font_manager_get_string_width_scaled(font, buf, scale);
|
||||
s++;
|
||||
extern void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, uint32_t codepoint, uint32_t color, float scale, float slope, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
font_manager_render_char_sloped(font, cur_x, baseline, codepoint, color, scale, slope, put_pixel);
|
||||
cur_x += font_manager_get_codepoint_width_scaled(font, codepoint, scale);
|
||||
}
|
||||
} else {
|
||||
draw_string_scaled_sloped(ux, uy, kernel_str, color, scale, slope);
|
||||
|
|
@ -563,11 +558,10 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
int cur_x = win->x + ux;
|
||||
const char *s = kernel_str;
|
||||
while (*s) {
|
||||
extern void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, char c, uint32_t color, float scale, float slope, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
font_manager_render_char_sloped(font, cur_x, baseline, *s, color, scale, slope, put_pixel);
|
||||
char buf[2] = {*s, 0};
|
||||
cur_x += font_manager_get_string_width_scaled(font, buf, scale);
|
||||
s++;
|
||||
extern void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, uint32_t codepoint, uint32_t color, float scale, float slope, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
font_manager_render_char_sloped(font, cur_x, baseline, codepoint, color, scale, slope, put_pixel);
|
||||
cur_x += font_manager_get_codepoint_width_scaled(font, codepoint, scale);
|
||||
}
|
||||
} else {
|
||||
draw_string_scaled_sloped(win->x + ux, win->y + uy, kernel_str, color, scale, slope);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,11 @@ static inline uint32_t alpha_blend(uint32_t bg, uint32_t fg, uint8_t alpha) {
|
|||
}
|
||||
|
||||
static ttf_font_t *default_font = NULL;
|
||||
static ttf_font_t *fallback_font = NULL;
|
||||
|
||||
void font_manager_set_fallback_font(ttf_font_t *font) {
|
||||
fallback_font = font;
|
||||
}
|
||||
|
||||
#define MAX_LOADED_FONTS 8
|
||||
typedef struct {
|
||||
|
|
@ -149,13 +154,49 @@ ttf_font_t* font_manager_load(const char *path, float size) {
|
|||
return font;
|
||||
}
|
||||
|
||||
void font_manager_render_char(ttf_font_t *font, int x, int y, char c, uint32_t color, void (*put_pixel_fn)(int, int, uint32_t)) {
|
||||
if (!font) font = default_font;
|
||||
if (!font) return;
|
||||
font_manager_render_char_scaled(font, x, y, c, color, font->pixel_height, put_pixel_fn);
|
||||
uint32_t utf8_decode(const char **s) {
|
||||
const unsigned char *u = (const unsigned char *)*s;
|
||||
if (!*u) return 0;
|
||||
|
||||
if (u[0] < 0x80) {
|
||||
*s = (const char *)(u + 1);
|
||||
return u[0];
|
||||
}
|
||||
|
||||
if ((u[0] & 0xE0) == 0xC0 && (u[1] & 0xC0) == 0x80) {
|
||||
*s = (const char *)(u + 2);
|
||||
return ((u[0] & 0x1F) << 6) | (u[1] & 0x3F);
|
||||
}
|
||||
|
||||
if ((u[0] & 0xF0) == 0xE0 && (u[1] & 0xC0) == 0x80 && (u[2] & 0xC0) == 0x80) {
|
||||
*s = (const char *)(u + 3);
|
||||
return ((u[0] & 0x0F) << 12) | ((u[1] & 0x3F) << 6) | (u[2] & 0x3F);
|
||||
}
|
||||
|
||||
if ((u[0] & 0xF8) == 0xF0 && (u[1] & 0xC0) == 0x80 && (u[2] & 0xC0) == 0x80 && (u[3] & 0xC0) == 0x80) {
|
||||
*s = (const char *)(u + 4);
|
||||
return ((u[0] & 0x07) << 18) | ((u[1] & 0x3F) << 12) | ((u[2] & 0x3F) << 6) | (u[3] & 0x3F);
|
||||
}
|
||||
|
||||
uint32_t codepoint = u[0];
|
||||
*s = (const char *)(u + 1);
|
||||
if (codepoint == 128) return 0x2014;
|
||||
if (codepoint == 129) return 0x2013;
|
||||
if (codepoint == 130) return 0x2022;
|
||||
if (codepoint == 131) return 0x2026;
|
||||
if (codepoint == 132) return 0x2122;
|
||||
if (codepoint == 133) return 0x20AC;
|
||||
if (codepoint == 134) return 0x00B7;
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
void font_manager_render_char_scaled(ttf_font_t *font, int x, int y, char c, uint32_t color, float scale, void (*put_pixel_fn)(int, int, uint32_t)) {
|
||||
void font_manager_render_char(ttf_font_t *font, int x, int y, uint32_t codepoint, uint32_t color, void (*put_pixel_fn)(int, int, uint32_t)) {
|
||||
if (!font) font = default_font;
|
||||
if (!font) return;
|
||||
font_manager_render_char_scaled(font, x, y, codepoint, color, font->pixel_height, put_pixel_fn);
|
||||
}
|
||||
|
||||
void font_manager_render_char_scaled(ttf_font_t *font, int x, int y, uint32_t codepoint, uint32_t color, float scale, void (*put_pixel_fn)(int, int, uint32_t)) {
|
||||
if (!font) font = default_font;
|
||||
if (!font) return;
|
||||
|
||||
|
|
@ -166,14 +207,10 @@ void font_manager_render_char_scaled(ttf_font_t *font, int x, int y, char c, uin
|
|||
|
||||
float real_scale = stbtt_ScaleForPixelHeight(info, scale);
|
||||
|
||||
int codepoint = (unsigned char)c;
|
||||
if (codepoint == 128) codepoint = 0x2014;
|
||||
if (codepoint == 129) codepoint = 0x2013;
|
||||
if (codepoint == 130) codepoint = 0x2022;
|
||||
if (codepoint == 131) codepoint = 0x2026;
|
||||
if (codepoint == 132) codepoint = 0x2122;
|
||||
if (codepoint == 133) codepoint = 0x20AC;
|
||||
if (codepoint == 134) codepoint = 0x00B7;
|
||||
if (stbtt_FindGlyphIndex(info, codepoint) == 0 && fallback_font) {
|
||||
info = (stbtt_fontinfo *)fallback_font->info;
|
||||
real_scale = stbtt_ScaleForPixelHeight(info, scale);
|
||||
}
|
||||
|
||||
bitmap = stbtt_GetCodepointBitmap(info, 0, real_scale, codepoint, &w, &h, &xoff, &yoff);
|
||||
|
||||
|
|
@ -193,7 +230,7 @@ void font_manager_render_char_scaled(ttf_font_t *font, int x, int y, char c, uin
|
|||
}
|
||||
}
|
||||
|
||||
void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, char c, uint32_t color, float scale, float slope, void (*put_pixel_fn)(int, int, uint32_t)) {
|
||||
void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, uint32_t codepoint, uint32_t color, float scale, float slope, void (*put_pixel_fn)(int, int, uint32_t)) {
|
||||
if (!font) font = default_font;
|
||||
if (!font) return;
|
||||
|
||||
|
|
@ -204,14 +241,10 @@ void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, char c, uin
|
|||
|
||||
float real_scale = stbtt_ScaleForPixelHeight(info, scale);
|
||||
|
||||
int codepoint = (unsigned char)c;
|
||||
if (codepoint == 128) codepoint = 0x2014;
|
||||
if (codepoint == 129) codepoint = 0x2013;
|
||||
if (codepoint == 130) codepoint = 0x2022;
|
||||
if (codepoint == 131) codepoint = 0x2026;
|
||||
if (codepoint == 132) codepoint = 0x2122;
|
||||
if (codepoint == 133) codepoint = 0x20AC;
|
||||
if (codepoint == 134) codepoint = 0x00B7;
|
||||
if (stbtt_FindGlyphIndex(info, codepoint) == 0 && fallback_font) {
|
||||
info = (stbtt_fontinfo *)fallback_font->info;
|
||||
real_scale = stbtt_ScaleForPixelHeight(info, scale);
|
||||
}
|
||||
|
||||
bitmap = stbtt_GetCodepointBitmap(info, 0, real_scale, codepoint, &w, &h, &xoff, &yoff);
|
||||
|
||||
|
|
@ -269,17 +302,33 @@ int font_manager_get_string_width_scaled(ttf_font_t *font, const char *s, float
|
|||
int width = 0;
|
||||
while (*s) {
|
||||
int advance, lsb;
|
||||
int codepoint = (unsigned char)*s;
|
||||
if (codepoint == 128) codepoint = 0x2014;
|
||||
if (codepoint == 129) codepoint = 0x2013;
|
||||
if (codepoint == 130) codepoint = 0x2022;
|
||||
if (codepoint == 131) codepoint = 0x2026;
|
||||
if (codepoint == 132) codepoint = 0x2122;
|
||||
if (codepoint == 133) codepoint = 0x20AC;
|
||||
if (codepoint == 134) codepoint = 0x00B7;
|
||||
stbtt_GetCodepointHMetrics(info, codepoint, &advance, &lsb);
|
||||
width += (int)(advance * real_scale + 0.5f);
|
||||
s++;
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
stbtt_fontinfo *current_info = info;
|
||||
float current_scale = real_scale;
|
||||
|
||||
if (stbtt_FindGlyphIndex(current_info, codepoint) == 0 && fallback_font) {
|
||||
current_info = (stbtt_fontinfo *)fallback_font->info;
|
||||
current_scale = stbtt_ScaleForPixelHeight(current_info, scale);
|
||||
}
|
||||
|
||||
stbtt_GetCodepointHMetrics(current_info, codepoint, &advance, &lsb);
|
||||
width += (int)(advance * current_scale + 0.5f);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
int font_manager_get_codepoint_width_scaled(ttf_font_t *font, uint32_t codepoint, float scale) {
|
||||
if (!font) font = default_font;
|
||||
if (!font) return 0;
|
||||
stbtt_fontinfo *info = (stbtt_fontinfo *)font->info;
|
||||
float real_scale = stbtt_ScaleForPixelHeight(info, scale);
|
||||
|
||||
if (stbtt_FindGlyphIndex(info, codepoint) == 0 && fallback_font) {
|
||||
info = (stbtt_fontinfo *)fallback_font->info;
|
||||
real_scale = stbtt_ScaleForPixelHeight(info, scale);
|
||||
}
|
||||
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(info, codepoint, &advance, &lsb);
|
||||
return (int)(advance * real_scale + 0.5f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,11 +44,14 @@ typedef struct {
|
|||
|
||||
bool font_manager_init(void);
|
||||
ttf_font_t* font_manager_load(const char *path, float size);
|
||||
void font_manager_render_char(ttf_font_t *font, int x, int y, char c, uint32_t color, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
void font_manager_render_char_scaled(ttf_font_t *font, int x, int y, char c, uint32_t color, float scale, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, char c, uint32_t color, float scale, float slope, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
void font_manager_set_fallback_font(ttf_font_t *font);
|
||||
uint32_t utf8_decode(const char **s);
|
||||
void font_manager_render_char(ttf_font_t *font, int x, int y, uint32_t codepoint, uint32_t color, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
void font_manager_render_char_scaled(ttf_font_t *font, int x, int y, uint32_t codepoint, uint32_t color, float scale, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
void font_manager_render_char_sloped(ttf_font_t *font, int x, int y, uint32_t codepoint, uint32_t color, float scale, float slope, void (*put_pixel_fn)(int, int, uint32_t));
|
||||
int font_manager_get_string_width(ttf_font_t *font, const char *s);
|
||||
int font_manager_get_string_width_scaled(ttf_font_t *font, const char *s, float scale);
|
||||
int font_manager_get_codepoint_width_scaled(ttf_font_t *font, uint32_t codepoint, float scale);
|
||||
|
||||
int font_manager_get_font_height_scaled(ttf_font_t *font, float scale);
|
||||
int font_manager_get_font_ascent_scaled(ttf_font_t *font, float scale);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ void graphics_init_fonts(void) {
|
|||
if (!g_current_ttf) {
|
||||
serial_write("[FONT] Falling back to bitmap font\n");
|
||||
}
|
||||
font_manager_set_fallback_font(font_manager_load("/Library/Fonts/Emoji/NotoEmoji-VariableFont_wght.ttf", 15.0f));
|
||||
}
|
||||
|
||||
void graphics_update_resolution(int width, int height, int bpp, void* fb_addr, int color_mode) {
|
||||
|
|
@ -540,7 +541,10 @@ int graphics_get_string_width_scaled(const char *s, float scale) {
|
|||
return font_manager_get_string_width_scaled(g_current_ttf, s, scale);
|
||||
}
|
||||
int len = 0;
|
||||
while (s && s[len]) len++;
|
||||
while (s && *s) {
|
||||
utf8_decode(&s);
|
||||
len++;
|
||||
}
|
||||
return len * 8; // Fallback bitmap width
|
||||
}
|
||||
|
||||
|
|
@ -559,30 +563,28 @@ void draw_string_scaled(int x, int y, const char *s, uint32_t color, float scale
|
|||
int line_height = font_manager_get_font_line_height_scaled(g_current_ttf, scale);
|
||||
|
||||
while (*s) {
|
||||
if (*s == '\n') {
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
if (codepoint == '\n') {
|
||||
cur_x = x;
|
||||
baseline += line_height;
|
||||
} else {
|
||||
font_manager_render_char_scaled(g_current_ttf, cur_x, baseline, *s, color, scale, put_pixel);
|
||||
// Advance by same rounded width that font_manager_get_string_width uses
|
||||
char buf[2] = {*s, 0};
|
||||
cur_x += font_manager_get_string_width_scaled(g_current_ttf, buf, scale);
|
||||
font_manager_render_char_scaled(g_current_ttf, cur_x, baseline, codepoint, color, scale, put_pixel);
|
||||
cur_x += font_manager_get_codepoint_width_scaled(g_current_ttf, codepoint, scale);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int cur_y = y;
|
||||
while (*s) {
|
||||
if (*s == '\n') {
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
if (codepoint == '\n') {
|
||||
cur_x = x;
|
||||
cur_y += 10;
|
||||
} else {
|
||||
draw_char(cur_x, cur_y, *s, color);
|
||||
draw_char(cur_x, cur_y, (codepoint < 128) ? (char)codepoint : '?', color);
|
||||
cur_x += 8;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -600,15 +602,14 @@ void draw_string_scaled_sloped(int x, int y, const char *s, uint32_t color, floa
|
|||
int line_height = font_manager_get_font_line_height_scaled(g_current_ttf, scale);
|
||||
|
||||
while (*s) {
|
||||
if (*s == '\n') {
|
||||
uint32_t codepoint = utf8_decode(&s);
|
||||
if (codepoint == '\n') {
|
||||
cur_x = x;
|
||||
baseline += line_height;
|
||||
} else {
|
||||
font_manager_render_char_sloped(g_current_ttf, cur_x, baseline, *s, color, scale, slope, put_pixel);
|
||||
char buf[2] = {*s, 0};
|
||||
cur_x += font_manager_get_string_width_scaled(g_current_ttf, buf, scale);
|
||||
font_manager_render_char_sloped(g_current_ttf, cur_x, baseline, codepoint, color, scale, slope, put_pixel);
|
||||
cur_x += font_manager_get_codepoint_width_scaled(g_current_ttf, codepoint, scale);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue