[backend] be a little more principled in loading fonts

This commit is contained in:
Milo Turner 2020-02-21 14:31:21 -05:00
parent 09a256ed90
commit fe4b533f72
3 changed files with 105 additions and 31 deletions

View File

@ -1,5 +1,6 @@
#include "../backend.h"
#include "../ctxt/theme.h"
#include "../util.h"
#include "../util/region.h"
#include "../concurrent/msgq.h"
#include "../concurrent/msg.h"
@ -145,25 +146,42 @@ struct ax_font_h {
TTF_Font* font;
};
static void load_fonts(
struct ax_backend* bac,
struct font_list* fl)
static int load_font(
struct rgn* rgn, const char* path, size_t size,
struct ax_font_h** out_fh, const char** out_err)
{
struct ax_font_h* fh = ralloc_typed(rgn, struct ax_font_h, 1);
if ((fh->font = TTF_OpenFont(path, size)) == NULL) {
*out_err = TTF_GetError();
return 1;
}
*out_fh = fh;
return 0;
}
static void load_fonts(struct ax_backend* bac, struct font_list* fl)
{
int rv = 0;
const char* err;
for (; fl != NULL; fl = fl->next) {
struct ax_theme* thm = fl->thm;
struct msgq* cb_mq = fl->cb_mq;
const char* path = thm->font_path[fl->cat];
size_t size = thm->font_size[fl->cat];
struct ax_font_h* handle = ralloc_typed(bac->rgn, struct ax_font_h, 1);
handle->font = TTF_OpenFont(path, size);
thm->font_handle[fl->cat] = handle;
if (ax__theme_is_loaded(thm)) {
struct ax_font_h* fh;
if ((rv = load_font(bac->rgn,
thm->font_path[fl->cat],
thm->font_size[fl->cat],
&fh, &err)) != 0) {
goto fail;
}
bool is_loaded = ax__theme_set_font_handle(thm, fl->cat, fh);
if (is_loaded) {
struct ax_msg_theme_loaded* m =
msgq_begin_send_typed(cb_mq, ax_msg_theme_loaded);
msgq_begin_send_typed(fl->cb_mq, ax_msg_theme_loaded);
m->theme = thm;
msgq_end_send(cb_mq);
msgq_end_send(fl->cb_mq);
}
}
fail:
ASSERT(rv == 0, "error loading font: %s", err);
}

View File

@ -12,6 +12,10 @@ static const char* default_font_path(struct rgn* rgn)
return "/usr/share/fonts/liberation/LiberationSans-Regular.ttf";
}
/* -----------------------------------------------------------------------------
* Theme builder functions
* -------------------------------------------------------------------------- */
void ax__theme_builder_init(struct ax_theme_builder* thmb, struct rgn* rgn)
{
thmb->rgn = rgn;
@ -83,7 +87,6 @@ void ax__theme_builder_finish(
if (thmb->err != NULL) {
thm->err = rstrdup(dst_rgn, thmb->err);
return;
}
const char* dflt_font_path = (thmb->dflt_font_path == NULL) ?
@ -97,6 +100,53 @@ void ax__theme_builder_finish(
dflt_font_path :
rstrdup(dst_rgn, thm->font_path[i]);
}
pthread_mutex_init(&thm->handles_mx, NULL);
rgn_pin(dst_rgn, thm, (void*) pthread_mutex_destroy);
}
/* -----------------------------------------------------------------------------
* Theme functions
* -------------------------------------------------------------------------- */
static inline bool is_loaded(struct ax_theme* thm)
{
for (size_t i = 0; i < AX_FONT__COUNT; i++) {
if (thm->font_handle[i] == NULL) {
return false;
}
}
return true;
}
struct ax_font_h* ax__theme_font_handle(
struct ax_theme* thm,
enum ax_font_cat i)
{
pthread_mutex_lock(&thm->handles_mx);
struct ax_font_h* h = thm->font_handle[i];
pthread_mutex_unlock(&thm->handles_mx);
return h;
}
bool ax__theme_is_loaded(struct ax_theme* thm)
{
pthread_mutex_lock(&thm->handles_mx);
bool l = is_loaded(thm);
pthread_mutex_unlock(&thm->handles_mx);
return l;
}
bool ax__theme_set_font_handle(
struct ax_theme* thm,
enum ax_font_cat i,
struct ax_font_h* h)
{
pthread_mutex_lock(&thm->handles_mx);
thm->font_handle[i] = h;
bool l = is_loaded(thm);
pthread_mutex_unlock(&thm->handles_mx);
return l;
}
void ax__theme_request_load(
@ -133,6 +183,7 @@ int ax__string_to_font_cat(const char* str, enum ax_font_cat* out_cat)
return 0;
}
/*
void ax__debug_theme(struct ax_theme* thm)
{
printf("=========\nTHEME INFO:\n");
@ -152,3 +203,4 @@ void ax__debug_theme(struct ax_theme* thm)
str, thm->font_path[i], thm->font_size[i]);
}
}
*/

View File

@ -3,6 +3,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <pthread.h>
struct rgn;
struct msgq;
@ -42,6 +43,7 @@ struct ax_theme {
size_t font_size[AX_FONT__COUNT];
const char* font_path[AX_FONT__COUNT];
struct ax_font_h* font_handle[AX_FONT__COUNT];
pthread_mutex_t handles_mx;
};
struct ax_theme_builder {
@ -74,22 +76,6 @@ void ax__theme_builder_finish(
struct rgn* dst_rgn,
struct ax_theme** out_thm);
void ax__theme_request_load(
struct ax_theme* thm,
struct msgq* req_mq,
struct msgq* res_mq);
static inline bool ax__theme_is_loaded(
struct ax_theme* thm)
{
for (size_t i = 0; i < AX_FONT__COUNT; i++) {
if (thm->font_handle[i] == NULL) {
return false;
}
}
return true;
}
static inline int64_t ax__theme_color(
struct ax_theme* thm,
enum ax_color_cat i)
@ -108,5 +94,23 @@ static inline const char* ax__theme_font(
return thm->font_path[i];
}
struct ax_font_h* ax__theme_font_handle(
struct ax_theme* thm,
enum ax_font_cat i);
bool ax__theme_is_loaded(
struct ax_theme* thm);
bool ax__theme_set_font_handle( // returns `true` if the font is now loaded
struct ax_theme* thm,
enum ax_font_cat i,
struct ax_font_h* h);
void ax__theme_request_load(
struct ax_theme* thm,
struct msgq* req_mq,
struct msgq* res_mq);
/*
void ax__debug_theme(struct ax_theme* thm);
*/