text: bring back shm-stored fonts provided by compositor

This commit is contained in:
K. Lange 2021-08-28 14:50:52 +09:00
parent 7d97b780e0
commit 4d68b0bc4a
24 changed files with 146 additions and 149 deletions

View File

@ -122,8 +122,8 @@ int main(int argc, char * argv[]) {
}
init_decorations();
_tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
_tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
_tt_font_thin = tt_font_from_shm("sans-serif");
_tt_font_bold = tt_font_from_shm("sans-serif.bold");
struct decor_bounds bounds;
decor_get_bounds(NULL, &bounds);

View File

@ -374,7 +374,7 @@ int main (int argc, char ** argv) {
win_width = 160;
win_height = 200;
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
tt_font_thin = tt_font_from_shm("sans-serif");
init_decorations();

View File

@ -1966,6 +1966,60 @@ static void yutani_display_resize_handle(int signum) {
signal(SIGWINEVENT, yutani_display_resize_handle);
}
#define FONT_PATH "/usr/share/fonts/"
#define FONT(a,b) {a, FONT_PATH b}
struct font_def {
char * identifier;
char * path;
};
/**
* TODO: This should be configurable...
*/
static struct font_def fonts[] = {
FONT("sans-serif", "truetype/dejavu/DejaVuSans.ttf"),
FONT("sans-serif.bold", "truetype/dejavu/DejaVuSans-Bold.ttf"),
FONT("sans-serif.italic", "truetype/dejavu/DejaVuSans-Oblique.ttf"),
FONT("sans-serif.bolditalic", "truetype/dejavu/DejaVuSans-BoldOblique.ttf"),
FONT("monospace", "truetype/dejavu/DejaVuSansMono.ttf"),
FONT("monospace.bold", "truetype/dejavu/DejaVuSansMono-Bold.ttf"),
FONT("monospace.italic", "truetype/dejavu/DejaVuSansMono-Oblique.ttf"),
FONT("monospace.bolditalic", "truetype/dejavu/DejaVuSansMono-BoldOblique.ttf"),
{NULL, NULL}
};
static char * precache_shmfont(char * ident, char * name) {
FILE * f = fopen(name, "r");
if (!f) return NULL;
size_t s = 0;
fseek(f, 0, SEEK_END);
s = ftell(f);
fseek(f, 0, SEEK_SET);
size_t shm_size = s;
char * font = shm_obtain(ident, &shm_size);
assert((shm_size >= s) && "shm_obtain returned too little memory to load a font into!");
fread(font, s, 1, f);
fclose(f);
return font;
}
static void load_fonts(yutani_globals_t * yg) {
int i = 0;
while (fonts[i].identifier) {
char tmp[100];
sprintf(tmp, "sys.%s.fonts.%s", yg->server_ident, fonts[i].identifier);
TRACE("Loading font %s -> %s", fonts[i].path, tmp);
if (!precache_shmfont(tmp, fonts[i].path)) {
TRACE(" ... failed.");
}
++i;
}
}
/**
* main
*/
@ -2030,6 +2084,8 @@ int main(int argc, char * argv[]) {
TRACE("pex bound? %d", server);
yg->server = server;
load_fonts(yg);
TRACE("Loading sprites...");
#define MOUSE_DIR "/usr/share/cursor/"
load_sprite(&yg->mouse_sprite, MOUSE_DIR "normal.png");

View File

@ -1847,8 +1847,8 @@ int main(int argc, char * argv[]) {
yctx = yutani_init();
init_decorations();
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
tt_font_thin = tt_font_from_shm("sans-serif");
tt_font_bold = tt_font_from_shm("sans-serif.bold");
int arg_ind = 1;

View File

@ -1,97 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2018 K. Lange
*
* font-server - Provides shared-memory fonts.
*
* This is an implementation of the shared memory font server
* from Yutani in ToaruOS 1.2.x. It allows applications to
* make use of the Freetype font rendering backend by providing
* a common set of font files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/shm.h>
#if 0
#include <toaru/trace.h>
#define TRACE_APP_NAME "font-server"
#else
#define TRACE(...)
#endif
#define FONT_PATH "/usr/share/fonts/"
#define FONT(a,b) {a, FONT_PATH b}
struct font_def {
char * identifier;
char * path;
};
static struct font_def fonts[] = {
FONT("sans-serif", "DejaVuSans.ttf"),
FONT("sans-serif.bold", "DejaVuSans-Bold.ttf"),
FONT("sans-serif.italic", "DejaVuSans-Oblique.ttf"),
FONT("sans-serif.bolditalic", "DejaVuSans-BoldOblique.ttf"),
FONT("monospace", "DejaVuSansMono.ttf"),
FONT("monospace.bold", "DejaVuSansMono-Bold.ttf"),
FONT("monospace.italic", "DejaVuSansMono-Oblique.ttf"),
FONT("monospace.bolditalic", "DejaVuSansMono-BoldOblique.ttf"),
{NULL, NULL}
};
/**
* Preload a font into the font cache.
*/
static char * precache_shmfont(char * ident, char * name) {
FILE * f = fopen(name, "r");
if (!f) return NULL;
size_t s = 0;
fseek(f, 0, SEEK_END);
s = ftell(f);
fseek(f, 0, SEEK_SET);
size_t shm_size = s;
char * font = shm_obtain(ident, &shm_size);
assert((shm_size >= s) && "shm_obtain returned too little memory to load a font into!");
fread(font, s, 1, f);
fclose(f);
return font;
}
/**
* Load all of the fonts into the cache.
*/
static void load_fonts(char * server) {
int i = 0;
while (fonts[i].identifier) {
char tmp[100];
sprintf(tmp, "sys.%s.fonts.%s", server, fonts[i].identifier);
TRACE("Loading font %s -> %s", fonts[i].path, tmp);
if (!precache_shmfont(tmp, fonts[i].path)) {
TRACE(" ... failed.");
}
++i;
}
}
int main(int argc, char * argv[]) {
/* Daemonize */
if (!fork()) {
load_fonts("fonts");
while (1) {
usleep(100000);
}
return 0;
}
return 0;
}

View File

@ -267,8 +267,8 @@ int main (int argc, char ** argv) {
yutani_flip(y, wina);
TRACE("... done.");
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
tt_font_thin = tt_font_from_shm("sans-serif");
tt_font_bold = tt_font_from_shm("sans-serif.bold");
redo_everything:
win_width = width;

View File

@ -230,7 +230,7 @@ int main(int argc, char ** argv) {
window = yutani_window_create(yctx, width, height);
yutani_window_move(yctx, window, 0, 0);
yutani_window_advertise(yctx, window, "gsudo");
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
tt_font_thin = tt_font_from_shm("sans-serif");
ctx = init_graphics_yutani_double_buffer(window);

View File

@ -349,10 +349,10 @@ int main(int argc, char * argv[]) {
yutani_window_move(yctx, main_window, yctx->display_width / 2 - main_window->width / 2, yctx->display_height / 2 - main_window->height / 2);
ctx = init_graphics_yutani_double_buffer(main_window);
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
tt_font_oblique = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Oblique.ttf");
tt_font_bold_oblique = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-BoldOblique.ttf");
tt_font_thin = tt_font_from_shm("sans-serif");
tt_font_bold = tt_font_from_shm("sans-serif.bold");
tt_font_oblique = tt_font_from_shm("sans-serif.italic");
tt_font_bold_oblique = tt_font_from_shm("sans-serif.bolditalic");
yutani_window_advertise_icon(yctx, main_window, APPLICATION_TITLE, "help");

View File

@ -462,8 +462,8 @@ int main(int argc, char * argv[]) {
yutani_window_move(yctx, main_window, yctx->display_width / 2 - main_window->width / 2, yctx->display_height / 2 - main_window->height / 2);
ctx = init_graphics_yutani_double_buffer(main_window);
tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
tt_font_thin = tt_font_from_shm("sans-serif");
tt_font_bold = tt_font_from_shm("sans-serif.bold");
yutani_window_advertise_icon(yctx, main_window, APPLICATION_TITLE, "package");

View File

@ -1534,10 +1534,10 @@ int main (int argc, char ** argv) {
/* Connect to window server */
yctx = yutani_init();
font = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
font_mono = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf");
font_mono_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf");
font = tt_font_from_shm("sans-serif");
font_bold = tt_font_from_shm("sans-serif.bold");
font_mono = tt_font_from_shm("monospace");
font_mono_bold = tt_font_from_shm("monospace.bold");
/* For convenience, store the display size */
width = yctx->display_width;

View File

@ -145,7 +145,7 @@ int main(int argc, char * argv[]) {
struct decor_bounds bounds;
decor_get_bounds(NULL, &bounds);
_tt_font = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
_tt_font = tt_font_from_shm("sans-serif");
window = yutani_window_create_flags(yctx, width + bounds.width, height + bounds.height, YUTANI_WINDOW_FLAG_DIALOG_ANIMATION);
req_center_x = yctx->display_width / 2;

View File

@ -2272,13 +2272,6 @@ int main(int argc, char ** argv) {
}
}
_tt_font_normal = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf");
_tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf");
_tt_font_oblique = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Oblique.ttf");
_tt_font_bold_oblique = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSansMono-BoldOblique.ttf");
_tt_font_fallback = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
_tt_font_japanese = tt_font_from_file("/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf"); /* Might not be present */
/* Initialize the windowing library */
yctx = yutani_init();
@ -2287,6 +2280,13 @@ int main(int argc, char ** argv) {
return 1;
}
_tt_font_normal = tt_font_from_shm("monospace");
_tt_font_bold = tt_font_from_shm("monospace.bold");
_tt_font_oblique = tt_font_from_shm("monospace.italic");
_tt_font_bold_oblique = tt_font_from_shm("monospace.bolditalic");
_tt_font_fallback = _tt_font_normal;
_tt_font_japanese = tt_font_from_file("/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf"); /* Might not be present */
/* Full screen mode forces window size to be that the display server */
if (_fullscreen) {
window_width = yctx->display_width;

View File

@ -315,8 +315,8 @@ int main(int argc, char * argv[]) {
}
init_decorations();
_tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
_tt_font_bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
_tt_font_thin = tt_font_from_shm("sans-serif");
_tt_font_bold = tt_font_from_shm("sans-serif.bold");
background = yutani_window_create_flags(yctx, yctx->display_width, yctx->display_height,
YUTANI_WINDOW_FLAG_DISALLOW_RESIZE | YUTANI_WINDOW_FLAG_DISALLOW_DRAG |

View File

@ -294,7 +294,7 @@ int main(int argc, char * argv[]) {
req_center_x = yctx->display_width / 2;
req_center_y = yctx->display_height / 2;
tt_font = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
tt_font = tt_font_from_shm("sans-serif");
get_default_wallpaper();
read_wallpapers();

View File

@ -1,8 +0,0 @@
#!/bin/sh
# Only start if we're likely to be running a GUI
export-cmd START kcmdline -g start
if equals? "$START" "--vga" then exit
if equals? "$START" "--headless" then exit
if stat -Lq /usr/share/fonts/DejaVuSansMono.ttf then font-server

View File

@ -4,7 +4,7 @@
#include <sys/types.h>
_Begin_C_Header
extern void * shm_obtain(char * path, size_t * size);
extern int shm_release(char * path);
extern void * shm_obtain(const char * path, size_t * size);
extern int shm_release(const char * path);
_End_C_Header

View File

@ -93,8 +93,8 @@ DECL_SYSCALL3(clone, uintptr_t, uintptr_t, void *);
DECL_SYSCALL1(sethostname, char *);
DECL_SYSCALL1(gethostname, char *);
DECL_SYSCALL2(mkdir, char *, unsigned int);
DECL_SYSCALL2(shm_obtain, char *, size_t *);
DECL_SYSCALL1(shm_release, char *);
DECL_SYSCALL2(shm_obtain, const char *, size_t *);
DECL_SYSCALL1(shm_release, const char *);
DECL_SYSCALL2(kill, int, int);
DECL_SYSCALL2(signal, int, void *);
DECL_SYSCALL3(recv,int,void*,int);

View File

@ -3,6 +3,7 @@
#include <stdint.h>
extern struct TT_Font * tt_font_from_file(const char * fileName);
extern struct TT_Font * tt_font_from_shm(const char * identifier);
extern int tt_glyph_for_codepoint(struct TT_Font * font, unsigned int codepoint);
extern void tt_draw_glyph(gfx_context_t * ctx, struct TT_Font * font, int x_offset, int y_offset, unsigned int glyph, uint32_t color);
extern void tt_set_size(struct TT_Font * font, float sizeInEm);

View File

@ -44,7 +44,7 @@ void ttk_button_draw(gfx_context_t * ctx, struct TTKButton * button) {
if (button->title[0] != '\033') {
if (!_tt_font_thin) {
_tt_font_thin = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
_tt_font_thin = tt_font_from_shm("sans-serif");
}
tt_set_size(_tt_font_thin, 13);
int label_width = tt_string_width(_tt_font_thin, button->title);

View File

@ -206,6 +206,6 @@ void decor_init() {
decor_check_button_press = check_button_press_fancy;
decor_get_bounds = get_bounds_fancy;
_tt_font = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
_tt_font = tt_font_from_shm("sans-serif.bold");
}

View File

@ -95,7 +95,7 @@ static void initialize_simple() {
decor_render_decorations = render_decorations_simple;
decor_check_button_press = check_button_press_simple;
decor_get_bounds = get_bounds_simple;
tt_font = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
tt_font = tt_font_from_shm("sans-serif");
}
void render_decorations(yutani_window_t * window, gfx_context_t * ctx, char * title) {

View File

@ -155,9 +155,9 @@ int markup_draw_string(gfx_context_t * ctx, int x, int y, const char * str, uint
}
void markup_text_init(void) {
dejaVuSans = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");
dejaVuSans_Bold = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf");
dejaVuSans_Oblique = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-Oblique.ttf");
dejaVuSans_BoldOblique = tt_font_from_file("/usr/share/fonts/truetype/dejavu/DejaVuSans-BoldOblique.ttf");
dejaVuSans = tt_font_from_shm("sans-serif");
dejaVuSans_Bold = tt_font_from_shm("sans-serif.bold");
dejaVuSans_Oblique = tt_font_from_shm("sans-serif.italic");
dejaVuSans_BoldOblique = tt_font_from_shm("sans-serif.bolditalic");
}

View File

@ -11,9 +11,12 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <toaru/graphics.h>
#include <toaru/hashmap.h>
#include <toaru/decodeutf8.h>
#include <toaru/spinlock.h>
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
@ -875,6 +878,48 @@ struct TT_Font * tt_font_from_file_mem(const char * fileName) {
return tt_font_from_memory(buf);
}
static hashmap_t * shm_font_cache = NULL;
static int volatile shm_font_lock = 0;
struct TT_Font * tt_font_from_shm(const char * identifier) {
spin_lock(&shm_font_lock);
if (!shm_font_cache) {
shm_font_cache = hashmap_create(10);
}
struct TT_Font * out = hashmap_get(shm_font_cache, (char*)identifier);
if (out) goto shm_success;
char * display = getenv("DISPLAY");
if (!display) goto shm_fail;
char fullIdentifier[1024];
snprintf(fullIdentifier, 1023, "sys.%s.fonts.%s", display, identifier);
size_t fontSize = 0;
void * fontData = shm_obtain(fullIdentifier, &fontSize);
if (fontSize == 0) {
shm_release(identifier);
goto shm_fail;
}
out = tt_font_from_memory(fontData);
hashmap_set(shm_font_cache, (char*)identifier, out);
shm_success:
spin_unlock(&shm_font_lock);
return out;
shm_fail:
spin_unlock(&shm_font_lock);
return NULL;
}
void tt_draw_string_shadow(gfx_context_t * ctx, struct TT_Font * font, char * string, int font_size, int left, int top, uint32_t text_color, uint32_t shadow_color, int blur) {
tt_set_size(font, font_size);
int w = tt_string_width(font, string);

View File

@ -1,13 +1,13 @@
#include <syscall.h>
#include <syscall_nums.h>
DEFN_SYSCALL2(shm_obtain, SYS_SHM_OBTAIN, char *, size_t *);
DEFN_SYSCALL1(shm_release, SYS_SHM_RELEASE, char *);
DEFN_SYSCALL2(shm_obtain, SYS_SHM_OBTAIN, const char *, size_t *);
DEFN_SYSCALL1(shm_release, SYS_SHM_RELEASE, const char *);
void * shm_obtain(char * path, size_t * size) {
void * shm_obtain(const char * path, size_t * size) {
return (void *)syscall_shm_obtain(path, size);
}
int shm_release(char * path) {
int shm_release(const char * path) {
return syscall_shm_release(path);
}