From c2aae50dcadca729adc91b41bc336c09e76ec391 Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Thu, 30 Jul 2020 20:55:17 -0700 Subject: [PATCH] Various improvements to SengokuRanceFont/fnl --- include/gfx/gfx.h | 17 +++- include/system4/fnl.h | 20 +++- src/fnl.c | 71 ++++++++++---- src/fnl_render.c | 52 ++++++----- src/hll/SengokuRanceFont.c | 184 ++++++++++++++++++++----------------- src/tools/fnl/fnldump.c | 10 +- 6 files changed, 224 insertions(+), 130 deletions(-) diff --git a/include/gfx/gfx.h b/include/gfx/gfx.h index bebc23d..3e4dd96 100644 --- a/include/gfx/gfx.h +++ b/include/gfx/gfx.h @@ -183,7 +183,22 @@ struct fnl_font_inst { int outline_size; }; +struct text_style { + unsigned font_type; + float size; + float bold_width; + SDL_Color color; + float edge_width; + SDL_Color edge_color; + float scale_x; + float space_scale_x; + float font_spacing; + + struct fnl_font_size *font_size; +}; + +struct fnl; struct fnl_font_face; -int fnl_draw_text(struct fnl_font_inst *font, Texture *dst, int x, int y, char *text); +int fnl_draw_text(struct fnl *fnl, struct text_style *ts, Texture *dst, int x, int y, char *text); #endif /* SYSTEM4_SDL_CORE_H */ diff --git a/include/system4/fnl.h b/include/system4/fnl.h index 2f9b242..57dbe85 100644 --- a/include/system4/fnl.h +++ b/include/system4/fnl.h @@ -18,39 +18,53 @@ #define SYSTEM4_FNL_H #include +#include struct fnl { + uint8_t *data; uint32_t filesize; uint32_t uk; uint32_t data_offset; uint32_t nr_fonts; struct fnl_font *fonts; + }; struct fnl_font { + struct fnl *fnl; uint32_t nr_faces; struct fnl_font_face *faces; + uint32_t nr_sizes; + struct fnl_font_size *sizes; +}; + +struct fnl_font_size { + unsigned face; + float size; + unsigned denominator; }; struct fnl_font_face { + struct fnl_font *font; uint32_t height; uint32_t uk; uint32_t nr_glyphs; struct fnl_glyph *glyphs; + float _sizes[11]; }; struct fnl_glyph { + uint32_t height; uint16_t real_width; uint32_t data_pos; uint32_t data_compsize; - // uncompressed data - unsigned long data_size; - uint8_t *data; }; struct fnl *fnl_open(const char *path); void fnl_free(struct fnl *fnl); struct fnl_glyph *fnl_get_glyph(struct fnl_font_face *font, uint16_t code); +uint8_t *fnl_glyph_data(struct fnl *fnl, struct fnl_glyph *g, unsigned long *size); +struct fnl_font_size *fnl_get_font_size(struct fnl_font *font, float size); #endif /* SYSTEM4_FNL_H */ diff --git a/src/fnl.c b/src/fnl.c index 313306a..818ac6d 100644 --- a/src/fnl.c +++ b/src/fnl.c @@ -16,6 +16,7 @@ #include #include +#include #include #include "system4.h" #include "system4/buffer.h" @@ -54,28 +55,47 @@ struct fnl_glyph *fnl_get_glyph(struct fnl_font_face *font, uint16_t code) if (index >= font->nr_glyphs) index = 0; - if (!font->glyphs[index].data_size) + if (!font->glyphs[index].data_pos) index = 0; return &font->glyphs[index]; } +/* + * Get the closest font size. + */ +struct fnl_font_size *fnl_get_font_size(struct fnl_font *font, float size) +{ + float min_diff = 9999; + struct fnl_font_size *closest = &font->sizes[0]; + for (unsigned i = 0; i < font->nr_sizes; i++) { + float diff = fabsf(font->sizes[i].size - size); + if (diff < min_diff) { + min_diff = diff; + closest = &font->sizes[i]; + } + } + return closest; +} + static void fnl_read_glyph(struct buffer *r, uint32_t height, struct fnl_glyph *dst) { + dst->height = height; dst->real_width = buffer_read_u16(r); dst->data_pos = buffer_read_int32(r); dst->data_compsize = buffer_read_int32(r); +} - if (!dst->data_pos) { - dst->data_size = 0; - dst->data = NULL; - return; +uint8_t *fnl_glyph_data(struct fnl *fnl, struct fnl_glyph *g, unsigned long *size) +{ + if (!g->data_pos) { + *size = 0; + return NULL; } - // uncompress... - dst->data_size = height * height * 4; // FIXME: determine real bound - dst->data = xmalloc(dst->data_size); - int rv = uncompress(dst->data, &dst->data_size, r->buf + dst->data_pos, dst->data_compsize); + *size = g->height * g->height * 4; // FIXME: determine real bound + uint8_t *data = xmalloc(*size); + int rv = uncompress(data, size, fnl->data + g->data_pos, g->data_compsize); if (rv != Z_OK) { if (rv == Z_BUF_ERROR) ERROR("uncompress failed: Z_BUF_ERROR"); @@ -84,6 +104,7 @@ static void fnl_read_glyph(struct buffer *r, uint32_t height, struct fnl_glyph * else if (rv == Z_DATA_ERROR) ERROR("uncompress failed: Z_DATA_ERROR"); } + return data; } static void fnl_read_font_face(struct buffer *r, struct fnl_font_face *dst) @@ -96,6 +117,10 @@ static void fnl_read_font_face(struct buffer *r, struct fnl_font_face *dst) for (size_t i = 0; i < dst->nr_glyphs; i++) { fnl_read_glyph(r, dst->height, &dst->glyphs[i]); } + + for (unsigned i = 0; i < 11; i++) { + dst->_sizes[i] = dst->height / (float)(i+2); + } } static void fnl_read_font(struct buffer *r, struct fnl_font *dst) @@ -104,21 +129,35 @@ static void fnl_read_font(struct buffer *r, struct fnl_font *dst) dst->faces = xcalloc(dst->nr_faces, sizeof(struct fnl_font_face)); for (size_t i = 0; i < dst->nr_faces; i++) { + dst->faces[i].font = dst; fnl_read_font_face(r, &dst->faces[i]); } + + dst->nr_sizes = dst->nr_faces * 11; + dst->sizes = xcalloc(dst->nr_sizes, sizeof(struct fnl_font_size)); + for (unsigned face = 0, s = 0; face < dst->nr_faces; face++) { + for (unsigned i = 0; i < 11; i++) { + dst->sizes[s++] = (struct fnl_font_size) { + .face = face, + .size = dst->faces[face]._sizes[i], + .denominator = i+2 + }; + } + } + } struct fnl *fnl_open(const char *path) { size_t filesize; struct fnl *fnl = xcalloc(1, sizeof(struct fnl)); - uint8_t *data = file_read(path, &filesize); + fnl->data = file_read(path, &filesize); - if (data[0] != 'F' || data[1] != 'N' || data[2] != 'A' || data[3] != '\0') + if (fnl->data[0] != 'F' || fnl->data[1] != 'N' || fnl->data[2] != 'A' || fnl->data[3] != '\0') goto err; struct buffer r; - buffer_init(&r, data, filesize); + buffer_init(&r, fnl->data, filesize); buffer_skip(&r, 4); fnl->uk = buffer_read_int32(&r); if (fnl->uk != 0) @@ -130,13 +169,13 @@ struct fnl *fnl_open(const char *path) fnl->fonts = xcalloc(fnl->nr_fonts, sizeof(struct fnl_font)); for (size_t i = 0; i < fnl->nr_fonts; i++) { + fnl->fonts[i].fnl = fnl; fnl_read_font(&r, &fnl->fonts[i]); } - free(data); return fnl; err: + free(fnl->data); free(fnl); - free(data); return NULL; } @@ -144,13 +183,11 @@ void fnl_free(struct fnl *fnl) { for (size_t font = 0; font < fnl->nr_fonts; font++) { for (size_t face = 0; face < fnl->fonts[font].nr_faces; face++) { - for (size_t glyph = 0; glyph < fnl->fonts[font].faces[face].nr_glyphs; glyph++) { - free(fnl->fonts[font].faces[face].glyphs[glyph].data); - } free(fnl->fonts[font].faces[face].glyphs); } free(fnl->fonts[font].faces); } free(fnl->fonts); + free(fnl->data); free(fnl); } diff --git a/src/fnl_render.c b/src/fnl_render.c index 001dc01..431a8f2 100644 --- a/src/fnl_render.c +++ b/src/fnl_render.c @@ -31,68 +31,73 @@ static void set_pixel(uint8_t *p, int w, int h, int x, int y, SDL_Color c) p[y*w*4 + x*4 + 3] = 255; } -static void render_outline(struct fnl_font_inst *font, uint8_t *surf, struct fnl_glyph *glyph, int x, int w, int h) +static void render_outline(struct text_style *ts, uint8_t *surf, uint8_t *data, unsigned long data_size, int x, int w, int h) { const int span = w * 4; - const int glyph_w = (glyph->data_size*8) / h; - const int size = 1.0 / font->scale * font->outline_size; + const int glyph_w = (data_size*8) / h; + const int size = ts->font_size->denominator * ts->edge_width; uint32_t p = 0; for (int row = h - 1; row >= 0; row--) { uint8_t *pos = surf + row*span + x*4; for (int col = 0; col < glyph_w; col++, p++, pos += 4) { - bool on = glyph->data[p/8] & (1 << (7 - p % 8)); + bool on = data[p/8] & (1 << (7 - p % 8)); if (!on) continue; int start_x = x + col - size; int start_y = row - size; for (int ol_row = 0; ol_row < size*2; ol_row++) { for (int ol_col = 0; ol_col < size*2; ol_col++) { - set_pixel(surf, w, h, start_x + ol_col, start_y + ol_row, font->outline_color); + set_pixel(surf, w, h, start_x + ol_col, start_y + ol_row, ts->edge_color); } } } } } -static void render_glyph(struct fnl_font_inst *font, uint8_t *surf, struct fnl_glyph *glyph, int x, int w, int h) +// TODO: cache glyph textures, render directly to dst texture +static void render_glyph(struct fnl_font_face *font, struct text_style *ts, uint8_t *surf, struct fnl_glyph *glyph, int x, int w, int h) { - const int span = w * 4; - const int glyph_w = (glyph->data_size*8) / h; + unsigned long data_size; + uint8_t *data = fnl_glyph_data(font->font->fnl, glyph, &data_size); - if (font->outline_size) - render_outline(font, surf, glyph, x, w, h); + const int span = w * 4; + const int glyph_w = (data_size*8) / h; + + if (ts->edge_width) + render_outline(ts, surf, data, data_size, x, w, h); uint32_t p = 0; for (int row = h - 1; row >= 0; row--) { uint8_t *pos = surf + row*span + x*4; for (int col = 0; col < glyph_w; col++, p++) { - bool on = glyph->data[p/8] & (1 << (7 - p % 8)); + bool on = data[p/8] & (1 << (7 - p % 8)); if (on) { - set_pixel(surf, w, h, x+col, row, font->color); + set_pixel(surf, w, h, x+col, row, ts->color); } pos += 4; } } + + free(data); } -static void render_text(struct fnl_font_inst *font, Texture *dst, char *text) +static void render_text(struct fnl_font_face *font, struct text_style *ts, Texture *dst, char *text) { // create array of fnl_glyph - const int height = font->font->height; + const int height = font->height; int len = sjis_count_char(text); struct fnl_glyph **glyphs = xcalloc(len, sizeof(struct fnl_glyph*)); for (int i = 0; i < len; i++) { - glyphs[i] = fnl_get_glyph(font->font, sjis_code(text)); + glyphs[i] = fnl_get_glyph(font, sjis_code(text)); text = sjis_skip_char(text); } // calculate width/height of text surface int width = 0; for (int i = 0; i < len; i++) { - //width += glyphs[i]->real_width; - width += (glyphs[i]->data_size*8)/height; + width += glyphs[i]->real_width; } // allocate memory for surface @@ -101,12 +106,14 @@ static void render_text(struct fnl_font_inst *font, Texture *dst, char *text) // render glyphs to surface int x = 0; for (int i = 0; i < len; i++) { - render_glyph(font, surf, glyphs[i], x, width, height); + render_glyph(font, ts, surf, glyphs[i], x, width, height); x += glyphs[i]->real_width; } // create texture from surface gfx_init_texture_with_pixels(dst, width, height, surf, GL_RGBA); + free(surf); + free(glyphs); } static void draw_text(Texture *dst, Texture *glyph, int x, int y, float scale) @@ -138,16 +145,17 @@ static void draw_text(Texture *dst, Texture *glyph, int x, int y, float scale) gfx_reset_framebuffer(GL_DRAW_FRAMEBUFFER, fbo); } -int fnl_draw_text(struct fnl_font_inst *font, Texture *dst, int x, int y, char *text) +int fnl_draw_text(struct fnl *fnl, struct text_style *ts, Texture *dst, int x, int y, char *text) { Texture rendered; - render_text(font, &rendered, text); + struct fnl_font_face *font = &fnl->fonts[ts->font_type].faces[ts->font_size->face]; + render_text(font, ts, &rendered, text); //glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); - draw_text(dst, &rendered, x, y, font->scale); + draw_text(dst, &rendered, x, y, 1.0 / ts->font_size->denominator); //glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); - int w = rendered.w; + int w = rendered.w / (float)ts->font_size->denominator; gfx_delete_texture(&rendered); return w; } diff --git a/src/hll/SengokuRanceFont.c b/src/hll/SengokuRanceFont.c index 5352d73..4201a5e 100644 --- a/src/hll/SengokuRanceFont.c +++ b/src/hll/SengokuRanceFont.c @@ -25,7 +25,6 @@ #include "gfx/gfx.h" #include "vm/page.h" #include "sact.h" -#include "kvec.h" #include "hll.h" #include "xsystem4.h" @@ -43,14 +42,49 @@ struct text_metrics sr_tm = { .outline_down = 1 }; -kvec_t(struct text_metrics) sp_tm; +struct text_style *sp_ts; +int nr_ts = 0; -static struct text_metrics *get_sp_metrics(int sp_no) +static struct text_style *get_sp_metrics(int sp_no) { - (void)kv_a(struct text_metrics, sp_tm, sp_no); - return &kv_A(sp_tm, sp_no); + if (sp_no > nr_ts) { + nr_ts = sp_no + 256; + sp_ts = xrealloc(sp_ts, nr_ts * sizeof(struct text_style)); + } + return sp_ts + sp_no; } +static unsigned get_font_type(int type) +{ + unsigned font = type - 256; + if (font >= fontlib->nr_fonts) { + WARNING("Invalid font type: %d", type); + // XXX: Really not sure why this is how it works... + font = type == 1 ? 2 : 1; + } + return font; +} + +/* +static unsigned get_font_face(int font, float height) +{ + float min_diff = 9999; + unsigned closest = 0; + + // FIXME: this isn't right; see comment for GetActualFontSize + for (unsigned i = 0; i < fontlib->fonts[font].nr_faces; i++) { + if (fontlib->fonts[font].faces[i].height == height) + return i; + float diff = fabsf(height - fontlib->fonts[font].faces[i].height); + if (diff < min_diff) { + min_diff = diff; + closest = i; + } + } + return closest; +} +*/ + void SengokuRanceFont_AlphaComposite(int spriteNumberDest, int destX, int destY, int spriteNumberSrc, int srcX, int srcY, int w, int h); void SengokuRanceFont_SetFontType(int type) @@ -154,98 +188,76 @@ void SengokuRanceFont_SP_TextNewLine(int spriteNumber, float fontSize); void SengokuRanceFont_SP_SetTextMetricsClassic(int sp_no, struct page *page) { - struct text_metrics *tm = get_sp_metrics(sp_no); - tm->color.r = page->values[0].i; - tm->color.g = page->values[1].i; - tm->color.b = page->values[2].i; - tm->color.a = 255; - tm->size = page->values[3].i; - tm->weight = page->values[4].i; - //tm->face = page->values[5].i; - tm->face = FONT_MINCHO; - tm->outline_left = page->values[6].i; - tm->outline_up = page->values[7].i; - tm->outline_right = page->values[8].i; - tm->outline_down = page->values[9].i; - tm->outline_color.r = page->values[10].i; - tm->outline_color.g = page->values[11].i; - tm->outline_color.b = page->values[12].i; - tm->outline_color.a = 255; + struct text_style *ts = get_sp_metrics(sp_no); + ts->font_type = get_font_type(256); + ts->color.r = page->values[0].i; + ts->color.g = page->values[1].i; + ts->color.b = page->values[2].i; + ts->color.a = 255; + ts->size = page->values[3].i; + //ts->weight = page->values[4].i; + //ts->face = page->values[5].i; + ts->edge_width = max(page->values[6].i, max(page->values[7].i, max(page->values[8].i, page->values[9].i))); + ts->edge_color.r = page->values[10].i; + ts->edge_color.g = page->values[11].i; + ts->edge_color.b = page->values[12].i; + ts->edge_color.a = 255; + ts->bold_width = 0; // FIXME: use weight? + ts->scale_x = 1; + ts->space_scale_x = 1; + ts->font_spacing = 1; + ts->font_size = fnl_get_font_size(&fontlib->fonts[ts->font_type], ts->size); } -static float boldwidth = 0; - -void SengokuRanceFont_SP_SetTextStyle(int sp_no, struct page *ts) +void SengokuRanceFont_SP_SetTextStyle(int sp_no, struct page *page) { - struct text_metrics *tm = get_sp_metrics(sp_no); - // FontType - tm->weight = FW_NORMAL; - tm->face = FONT_MINCHO; - tm->size = ts->values[1].f; - // BoldWidth - boldwidth = ts->values[2].f; - tm->color.r = ts->values[3].i; - tm->color.g = ts->values[4].i; - tm->color.b = ts->values[5].i; - tm->color.a = 255; - tm->outline_left = ts->values[6].f; - tm->outline_up = ts->values[6].f; - tm->outline_right = ts->values[6].f; - tm->outline_down = ts->values[6].f; - tm->outline_color.r = ts->values[7].i; - tm->outline_color.g = ts->values[8].i; - tm->outline_color.b = ts->values[9].i; - tm->outline_color.a = 255; - // ScaleX - // SpaceScaleX - // FontSpacing -} + struct text_style *ts = get_sp_metrics(sp_no); + ts->font_type = get_font_type(page->values[0].i < 0 ? 256 : page->values[0].i); + ts->size = page->values[1].f; + ts->bold_width = page->values[2].f < 0 ? 0 : page->values[2].f; + ts->color.r = page->values[3].i < 0 ? 255 : page->values[3].i; + ts->color.g = page->values[4].i < 0 ? 255 : page->values[4].i; + ts->color.b = page->values[5].i < 0 ? 255 : page->values[5].i; + ts->color.a = 255; + ts->edge_width = page->values[6].f < 0 ? 0 : page->values[6].f; + ts->edge_color.r = page->values[7].i < 0 ? 0 : page->values[7].i; + ts->edge_color.g = page->values[8].i < 0 ? 0 : page->values[8].i; + ts->edge_color.b = page->values[9].i < 0 ? 0 : page->values[9].i; + ts->edge_color.a = 255; + ts->scale_x = page->values[10].f < 0 ? 1 : page->values[10].f; + ts->space_scale_x = page->values[11].f < 0 ? 1 : page->values[11].f; + ts->font_spacing = page->values[12].f < 0 ? 1 : page->values[12].f; + ts->font_size = fnl_get_font_size(&fontlib->fonts[ts->font_type], ts->size); -void SengokuRanceFont_SP_TextDrawClassic(int sp_no, struct string *text) -{ - _sact_SP_TextDraw(sp_no, text, &sr_tm); -} - -static struct fnl_font_face *get_font(uint32_t height) -{ - int min_diff = 9999; - struct fnl_font_face *closest = NULL; - for (uint32_t i = 0; i < fontlib->fonts[0].nr_faces; i++) { - if (fontlib->fonts[0].faces[i].height == height) - return &fontlib->fonts[0].faces[i]; - int diff = abs((int)height - (int)fontlib->fonts[0].faces[i].height); - if (diff < min_diff) { - min_diff = diff; - closest = &fontlib->fonts[0].faces[i]; - } + if (ts->scale_x != 1.0) { + WARNING("X SCALE = %f", ts->scale_x); } - return closest; + } void SengokuRanceFont_SP_TextDraw(int sp_no, struct string *text) { struct sact_sprite *sp = sact_get_sprite(sp_no); - struct text_metrics *tm = get_sp_metrics(sp_no); - struct fnl_font_face *font = get_font(tm->size); - if (!font) { - WARNING("No font for size %u", tm->size); - return; + struct text_style *ts = get_sp_metrics(sp_no); + + // in case of uninitialized text style... + if (ts->font_type >= fontlib->nr_fonts) { + ts->font_type = 0; + } + if (ts->size < 8) { + ts->size = 8; + } + if (!ts->font_size) { + ts->font_size = fnl_get_font_size(&fontlib->fonts[ts->font_type], ts->size); } if (!sp->text.texture.handle) { - SDL_Color c = tm->color; + SDL_Color c = ts->color; c.a = 0; gfx_init_texture_with_color(&sp->text.texture, sp->rect.w, sp->rect.h, c); } - struct fnl_font_inst inst = { - .font = font, - .scale = 1.0 / (font->height / tm->size), - .color = tm->color, - .outline_color = tm->outline_color, - .outline_size = tm->outline_left - }; - sp->text.pos.x += fnl_draw_text(&inst, &sp->text.texture, sp->text.pos.x, sp->text.pos.y, text->text); + sp->text.pos.x += fnl_draw_text(fontlib, ts, &sp->text.texture, sp->text.pos.x, sp->text.pos.y, text->text); } void SengokuRanceFont_SP_TextDrawPreload(int spriteNumber, struct string *text); @@ -266,9 +278,10 @@ float SengokuRanceFont_SP_GetEdgeWidth(int spriteNumber); float SengokuRanceFont_SP_GetScaleX(int spriteNumber); float SengokuRanceFont_SP_GetSpaceScaleX(int spriteNumber); -float SengokuRanceFont_GetActualFontSize(int fontType, float fontSize) +float SengokuRanceFont_GetActualFontSize(int font_type, float font_size) { - return fontSize; + font_type = get_font_type(font_type); + return fnl_get_font_size(&fontlib->fonts[font_type], font_size)->size; } float SengokuRanceFont_GetActualFontSizeRoundDown(int fontType, float fontSize); @@ -278,7 +291,7 @@ int SengokuRanceFont_SP_GetReduceDescender(int spriteNumber); void SengokuRanceFont_SP_SetReduceDescender(int spriteNumber, int reduceDescender) { - + WARNING("SengokuRanceFont.SP_SetReduceDescender(%d, %d)", spriteNumber, reduceDescender); } void SengokuRanceFont_ModuleInit(void) @@ -300,6 +313,8 @@ void SengokuRanceFont_ModuleInit(void) fontlib = fnl_open(path); if (!(fontlib = fnl_open(path))) ERROR("Error opening font library '%s'", path); + if (fontlib->nr_fonts < 1) + ERROR("Font library doesn't contain any fonts"); break; } @@ -344,7 +359,8 @@ HLL_LIBRARY(SengokuRanceFont, //HLL_EXPORT(SP_TextNewLine, SengokuRanceFont_SP_TextNewLine), HLL_EXPORT(SP_SetTextMetricsClassic, SengokuRanceFont_SP_SetTextMetricsClassic), HLL_EXPORT(SP_SetTextStyle, SengokuRanceFont_SP_SetTextStyle), - HLL_EXPORT(SP_TextDrawClassic, SengokuRanceFont_SP_TextDrawClassic), + // XXX: I'm really not sure what the difference is supposed to be between these two + HLL_EXPORT(SP_TextDrawClassic, SengokuRanceFont_SP_TextDraw), HLL_EXPORT(SP_TextDraw, SengokuRanceFont_SP_TextDraw), //HLL_EXPORT(SP_TextDrawPreload, SengokuRanceFont_SP_TextDrawPreload), //HLL_EXPORT(SP_SetFontSize, SengokuRanceFont_SP_SetFontSize), diff --git a/src/tools/fnl/fnldump.c b/src/tools/fnl/fnldump.c index 0017e61..6f2f405 100644 --- a/src/tools/fnl/fnldump.c +++ b/src/tools/fnl/fnldump.c @@ -120,7 +120,7 @@ int main(int argc, char *argv[]) // extract glyphs for (size_t g = 0; g < font_face->nr_glyphs; g++) { struct fnl_glyph *glyph = &font_face->glyphs[g]; - if (!glyph->data) + if (!glyph->data_pos) continue; sprintf(path, "%s/font_%u/face_%u/glyph_%u.webp", output_dir, (unsigned)font, (unsigned)face, (unsigned)g); @@ -129,9 +129,13 @@ int main(int argc, char *argv[]) ERROR("fopen failed: %s", strerror(errno)); } + unsigned long data_size; + uint8_t *data = fnl_glyph_data(fnl, glyph, &data_size); + uint32_t height = font_face->height; - uint32_t width = (glyph->data_size*8) / height; - write_bitmap(f, width, height, glyph->data); + uint32_t width = (data_size*8) / height; + write_bitmap(f, width, height, data); + free(data); fclose(f); } }