diff --git a/include/gfx/gfx.h b/include/gfx/gfx.h index 114a4d9..13d32ae 100644 --- a/include/gfx/gfx.h +++ b/include/gfx/gfx.h @@ -142,6 +142,7 @@ void gfx_copy_amap_height_blur(Texture *dst, int dx, int dy, Texture *src, int s void gfx_copy_with_alpha_map(Texture *dst, int dx, int dy, Texture *src, int sx, int sy, int w, int h); void gfx_fill_with_alpha(Texture *dst, int x, int y, int w, int h, int r, int g, int b, int a); void gfx_copy_stretch_with_alpha_map(Texture *dst, int dx, int dy, int dw, int dh, Texture *src, int sx, int sy, int sw, int sh); +void gfx_draw_glyph(Texture *dst, float dx, int dy, Texture *glyph, SDL_Color color, float scale_x, float bold_width); enum { FW_NORMAL = 400, @@ -211,6 +212,8 @@ struct fnl_font_inst { int outline_size; }; +struct fnl_render_size; + struct text_style { unsigned font_type; float size; @@ -222,13 +225,14 @@ struct text_style { float space_scale_x; float font_spacing; - struct fnl_font_size *font_size; + struct fnl_render_size *font_size; }; -struct fnl; -struct fnl_font_face; -float fnl_draw_text(struct fnl *fnl, struct text_style *ts, Texture *dst, float x, int y, char *text); -float fnl_size_text(struct fnl *fnl, struct text_style *ts, char *text); -void fnl_renderer_free(struct fnl *fnl); +void fnl_renderer_init(const char *path); +void fnl_renderer_fini(void); +float fnl_draw_text(struct text_style *ts, Texture *dst, float x, int y, char *text); +float fnl_size_text(struct text_style *ts, char *text); +float fnl_get_actual_font_size(int font_type, float size); +float fnl_get_actual_font_size_round_down(int font_type, float size); #endif /* SYSTEM4_SDL_CORE_H */ diff --git a/shaders/dilate.f.glsl b/shaders/dilate.f.glsl new file mode 100644 index 0000000..b105b8f --- /dev/null +++ b/shaders/dilate.f.glsl @@ -0,0 +1,47 @@ +/* Copyright (C) 2019 Nunuhara Cabbage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +uniform sampler2D tex; +uniform float threshold; +uniform vec4 color; + +in vec2 tex_coord; +out vec4 frag_color; + +void main() { + // the fractional part of threshold becomes a weight value for the + // edge pixels + int size = int(floor(threshold)); + int cutoff = size + 1; + float edge_weight = fract(threshold); + vec2 tex_size = textureSize(tex, 0).xy; + + float a_out = 0; + + for (int x = -cutoff; x <= cutoff; x++) { + for (int y = -cutoff; y <= cutoff; y++) { + float d = distance(vec2(x, y), vec2(0, 0)); + if (d > threshold) + continue; + float a = texture(tex, tex_coord + vec2(x, y) / tex_size).a; + if (d > size) + a *= edge_weight; + a_out += a; + } + } + + frag_color = vec4(color.rgb, min(a_out, 1.0)); +} diff --git a/src/draw.c b/src/draw.c index bd5fac3..4603481 100644 --- a/src/draw.c +++ b/src/draw.c @@ -69,6 +69,7 @@ static struct copy_shader fill_amap_over_border_shader; static struct copy_shader fill_amap_under_border_shader; static struct copy_shader hitbox_shader; static struct copy_shader hitbox_noblend_shader; +static struct copy_shader dilate_shader; static void prepare_copy_shader(struct gfx_render_job *job, void *data) { @@ -132,6 +133,9 @@ void gfx_draw_init(void) // hitbox shader which ignores alpha component of texture (a=1) load_copy_shader(&hitbox_noblend_shader, "shaders/render.v.glsl", "shaders/hitbox_noblend.f.glsl"); + + // shader that dilates every pixel (for bold/outline text rendering) + load_copy_shader(&dilate_shader, "shaders/render.v.glsl", "shaders/dilate.f.glsl"); } static void run_draw_shader(Shader *s, Texture *dst, Texture *src, mat4 mw_transform, mat4 wv_transform, struct copy_data *data) @@ -767,3 +771,25 @@ void gfx_copy_stretch_with_alpha_map(Texture *dst, int dx, int dy, int dw, int d restore_blend_mode(); } + +// XXX: Not an actual DrawGraph function; used for rendering text +void gfx_draw_glyph(Texture *dst, float dx, int dy, Texture *glyph, SDL_Color color, float scale_x, float bold_width) +{ + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + struct copy_data data = STRETCH_DATA( + roundf(dx), dy, glyph->w * scale_x, glyph->h, + 0, 0, glyph->w, glyph->h); + data.r = color.r / 255.0; + data.g = color.g / 255.0; + data.b = color.b / 255.0; + + if (bold_width < 0.01) { + run_copy_shader(&blend_amap_color_shader.s, dst, glyph, &data); + } else { + data.threshold = bold_width; + run_copy_shader(&dilate_shader.s, dst, glyph, &data); + } + + restore_blend_mode(); +} diff --git a/src/fnl_render.c b/src/fnl_render.c index b351c31..cdd8d7c 100644 --- a/src/fnl_render.c +++ b/src/fnl_render.c @@ -22,123 +22,313 @@ #include "system4/fnl.h" #include "system4/utfsjis.h" #include "gfx/gfx.h" +#include "xsystem4.h" -static void draw_glyph(Texture *dst, float x, int y, Texture *glyph, float scale_x, float scale_y) -{ - GLuint fbo = gfx_set_framebuffer(GL_DRAW_FRAMEBUFFER, dst, roundf(x), y, glyph->w, glyph->h); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - mat4 mw_transform = MAT4( - glyph->w * scale_x, 0, 0, 0, - 0, glyph->h * scale_y, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - mat4 wv_transform = WV_TRANSFORM(glyph->w, glyph->h); - struct gfx_render_job job = { - .texture = glyph->handle, - .world_transform = mw_transform[0], - .view_transform = wv_transform[0], - .data = glyph - }; - gfx_render(&job); - - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); - gfx_reset_framebuffer(GL_DRAW_FRAMEBUFFER, fbo); -} - -struct fnl_glyph_texture { - Texture t; - SDL_Color c; +// Rendered glyph: pixels stored in GPU memory. +struct fnl_render_glyph { + float advance; + Texture texture; }; -enum glyph_texture_type { - FONT_TEXTURE = 0, - EDGE_TEXTURE = 1 +// Bitmap glyph: pixels stored in normal memory to be used when creating +// fnl_render_glyph objects. +struct fnl_bitmap_glyph { + unsigned width; + unsigned height; + unsigned advance; + uint8_t *pixels; }; -static Texture *get_glyph_texture(struct fnl_rendered_glyph *glyph, SDL_Color *c, - enum glyph_texture_type type) +// Object representing a bitmap font size. +struct fnl_bitmap { + struct fnl_font_face *face; + struct fnl_bitmap_glyph **glyphs; + unsigned nr_glyphs; +}; + +// Object representing a rendered font size. +struct fnl_render_size { + struct fnl_bitmap *bitmap; + float size; + unsigned denominator; + struct fnl_render_glyph **glyphs; + unsigned nr_glyphs; +}; + +// Object representing a font for rendering. +struct fnl_render_font { + struct fnl_bitmap *bitmaps; + unsigned nr_bitmaps; + struct fnl_render_size *sizes; + unsigned nr_sizes; +}; + +static struct fnl *fontlib = NULL; +static struct fnl_render_font *fonts = NULL; +static unsigned nr_fonts = 0; + +void fnl_renderer_init(const char *path) { - if (!glyph->data) { - glyph->data = xcalloc(2, sizeof(struct fnl_glyph_texture)); - } + if (!(fontlib = fnl_open(path))) + ERROR("Error opening font library '%s'", display_utf0(path)); + if (fontlib->nr_fonts < 1) + ERROR("Font library doesn't contain any fonts"); - struct fnl_glyph_texture *g = glyph->data; - g += type; + fonts = xcalloc(fontlib->nr_fonts, sizeof(struct fnl_render_font)); + nr_fonts = fontlib->nr_fonts; - if (!g->t.handle) { - gfx_init_texture_amap(&g->t, glyph->width, glyph->height, glyph->pixels, *c); - g->c = *c; - return &g->t; - } + for (unsigned i = 0; i < nr_fonts; i++) { + struct fnl_font *lib_font = &fontlib->fonts[i]; + struct fnl_render_font *font = &fonts[i]; - if (g->c.r != c->r || g->c.g != c->g || g->c.b != c->b) { - gfx_fill(&g->t, 0, 0, g->t.w, g->t.h, c->r, c->g, c->b); - g->c = *c; + font->nr_bitmaps = lib_font->nr_faces; + font->bitmaps = xcalloc(font->nr_bitmaps, sizeof(struct fnl_bitmap)); + for (unsigned i = 0; i < font->nr_bitmaps; i++) { + struct fnl_bitmap *bitmap = &font->bitmaps[i]; + bitmap->face = &lib_font->faces[i]; + bitmap->nr_glyphs = bitmap->face->nr_glyphs; + bitmap->glyphs = xcalloc(bitmap->nr_glyphs, sizeof(struct fnl_bitmap_glyph*)); + } + + font->nr_sizes = font->nr_bitmaps * 12; + font->sizes = xcalloc(font->nr_sizes, sizeof(struct fnl_render_size)); + for (unsigned i = 0; i < font->nr_bitmaps; i++) { + struct fnl_bitmap *bitmap = &font->bitmaps[i]; + struct fnl_render_size *sizes = &font->sizes[i*12]; + for (unsigned i = 0; i < 12; i++) { + sizes[i].bitmap = bitmap; + sizes[i].size = bitmap->face->height / (float)(i+1); + sizes[i].denominator = i + 1; + sizes[i].nr_glyphs = bitmap->nr_glyphs; + sizes[i].glyphs = xcalloc(sizes[i].nr_glyphs, sizeof(struct fnl_render_glyph*)); + } + } } - return &g->t; } -static void draw_glyph_outline(Texture *dst, float x, int y, Texture *glyph, struct text_style *ts) +static void fnl_free_font(struct fnl_render_font *font) { - float edge_width = roundf(ts->edge_width); - draw_glyph(dst, x-edge_width, y, glyph, ts->scale_x, 1.0); - draw_glyph(dst, x+edge_width, y, glyph, ts->scale_x, 1.0); - draw_glyph(dst, x, y-edge_width, glyph, ts->scale_x, 1.0); - draw_glyph(dst, x, y+edge_width, glyph, ts->scale_x, 1.0); + for (unsigned i = 0; i < font->nr_bitmaps; i++) { + for (unsigned g = 0; g < font->bitmaps[i].nr_glyphs; g++) { + if (!font->bitmaps[i].glyphs[g]) + continue; + free(font->bitmaps[i].glyphs[g]->pixels); + free(font->bitmaps[i].glyphs[g]); + } + free(font->bitmaps[i].glyphs); + } + free(font->bitmaps); + + for (unsigned i = 0; i < font->nr_sizes; i++) { + for (unsigned g = 0; g < font->sizes[i].nr_glyphs; g++) { + if (!font->sizes[i].glyphs[g]) + continue; + gfx_delete_texture(&font->sizes[i].glyphs[g]->texture); + free(font->sizes[i].glyphs[g]); + } + free(font->sizes[i].glyphs); + } + free(font->sizes); } -float fnl_draw_text(struct fnl *fnl, struct text_style *ts, Texture *dst, float x, int y, char *text) +void fnl_renderer_fini(void) { + for (int i = 0; i < nr_fonts; i++) { + fnl_free_font(&fonts[i]); + } + free(fonts); + fonts = NULL; + nr_fonts = 0; + + fnl_free(fontlib); + fontlib = NULL; +} + +static unsigned get_font_type(int type) +{ + unsigned font = type - 256; + if (font >= 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 struct fnl_render_size *_fnl_get_actual_font_size(int font_type, float size) +{ + struct fnl_render_font *font = &fonts[get_font_type(font_type)]; + + float min_diff = 9999; + struct fnl_render_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 struct fnl_render_size *_fnl_get_actual_font_size_round_down(int font_type, float size) +{ + struct fnl_render_font *font = &fonts[get_font_type(font_type)]; + + float min_diff = 9999; + struct fnl_render_size *closest = &font->sizes[0]; + for (unsigned i = 0; i < font->nr_sizes; i++) { + if (font->sizes[i].size > size) + continue; + float diff = fabsf(font->sizes[i].size - size); + if (diff < min_diff) { + min_diff = diff; + closest = &font->sizes[i]; + } + } + return closest; +} + +float fnl_get_actual_font_size(int font_type, float size) +{ + return _fnl_get_actual_font_size(font_type, size)->size; +} + +float fnl_get_actual_font_size_round_down(int font_type, float size) +{ + return _fnl_get_actual_font_size_round_down(font_type, size)->size; +} + +static struct fnl_bitmap_glyph *fnl_get_bitmap_glyph(struct fnl_bitmap *bitmap, unsigned index) +{ + if (bitmap->glyphs[index]) + return bitmap->glyphs[index]; + + unsigned long data_size; + uint8_t *data = fnl_glyph_data(fontlib, &bitmap->face->glyphs[index], &data_size); + + const int glyph_w = (data_size*8) / bitmap->face->height; + const int glyph_h = bitmap->face->height; + + struct fnl_bitmap_glyph *out = xmalloc(sizeof(struct fnl_bitmap_glyph)); + out->width = glyph_w; + out->height = glyph_h; + out->advance = bitmap->face->glyphs[index].real_width; + out->pixels = xmalloc(glyph_w * glyph_h); + + // expand 1-bit bitmap to 8-bit + for (unsigned i = 0; i < glyph_w * glyph_h; i++) { + unsigned row = (glyph_h - 1) - i / glyph_w; + unsigned col = i % glyph_w; + bool on = data[i/8] & (1 << (7 - i % 8)); + out->pixels[row*glyph_w + col] = on ? 255 : 0; + } + + free(data); + bitmap->glyphs[index] = out; + return out; +} + +static struct fnl_render_glyph *fnl_render_glyph(struct fnl_render_size *size, uint16_t code) +{ + unsigned int index = fnl_char_to_index(code); + if (index >= size->nr_glyphs) + return NULL; + if (size->glyphs[index]) + return size->glyphs[index]; + if (!size->bitmap->face->glyphs[index].data_pos) + return NULL; + + struct fnl_bitmap_glyph *fullsize = fnl_get_bitmap_glyph(size->bitmap, index); + struct fnl_render_glyph *rendered = xmalloc(sizeof(struct fnl_render_glyph)); + rendered->advance = (float)fullsize->advance / (float)size->denominator; + const unsigned width = fullsize->width / size->denominator; + const unsigned height = fullsize->height / size->denominator; + + // Sample each pixel in `size->denominator`-sized blocks and compute the average. + // TODO: no need to sample every single pixel; 4 should be fine? + uint8_t *pixels = xmalloc(width * height); + unsigned *acc = xcalloc(width * height, sizeof(unsigned)); + for (unsigned i = 0; i < width * height; i++) { + unsigned dst_row = i / width; + unsigned dst_col = i % width; + for (unsigned r = 0; r < size->denominator; r++) { + unsigned src_row = dst_row * size->denominator + r; + for (unsigned c = 0; c < size->denominator; c++) { + unsigned src_col = dst_col * size->denominator + c; + acc[i] += fullsize->pixels[src_row*fullsize->width + src_col]; + } + } + pixels[i] = acc[i] / (size->denominator * size->denominator); + } + gfx_init_texture_amap(&rendered->texture, width, height, pixels, (SDL_Color){0,0,0,0}); + size->glyphs[index] = rendered; + + free(pixels); + free(acc); + return rendered; +} + +float fnl_draw_text(struct text_style *ts, Texture *dst, float x, int y, char *text) +{ + if (!ts->font_size) { + ts->font_size = _fnl_get_actual_font_size(ts->font_type, ts->size); + } + int len = sjis_count_char(text); - struct fnl_rendered_glyph **glyphs = xmalloc(len * sizeof(struct fnl_rendered_glyph*)); + struct fnl_render_glyph **glyphs = xmalloc(len * sizeof(struct fnl_render_glyph*)); for (int i = 0; i < len; i++) { glyphs[i] = fnl_render_glyph(ts->font_size, sjis_code(text)); text = sjis_skip_char(text); } float original_x = x; - if (ts->edge_width > 0.5) { + if (ts->edge_width > 0.1) { for (int i = 0; i < len; i++) { - Texture *t = get_glyph_texture(glyphs[i], &ts->edge_color, EDGE_TEXTURE); - draw_glyph_outline(dst, x, y, t, ts); - x += glyphs[i]->advance * ts->scale_x; + gfx_draw_glyph(dst, x, y, &glyphs[i]->texture, ts->edge_color, ts->scale_x, ts->edge_width); + x += glyphs[i]->advance * ts->scale_x + ts->font_spacing; } } x = original_x; for (int i = 0; i < len; i++) { - Texture *t = get_glyph_texture(glyphs[i], &ts->color, FONT_TEXTURE); - draw_glyph(dst, x, y, t, ts->scale_x, 1.0); - x += glyphs[i]->advance * ts->scale_x; + gfx_draw_glyph(dst, x, y, &glyphs[i]->texture, ts->color, ts->scale_x, ts->bold_width); + x += glyphs[i]->advance * ts->scale_x + ts->font_spacing; } free(glyphs); return x - original_x; } -float fnl_size_text(struct fnl *fnl, struct text_style *ts, char *text) +static float _fnl_size_char(struct fnl_render_size *size, uint16_t code) { - struct fnl_font_face *font = ts->font_size->face; - int width = 0; - int len = sjis_count_char(text); - for (int i = 0; i < len; i++) { - width += fnl_get_glyph(font, sjis_code(text))->real_width; - text = sjis_skip_char(text); + unsigned index = fnl_char_to_index(code); + if (index > size->nr_glyphs) + return 0.0; + if (!size->bitmap->face->glyphs[index].data_pos) + return 0.0; + return (float)size->bitmap->face->glyphs[index].real_width / (float)size->denominator; +} + +float fnl_size_char(struct text_style *ts, uint16_t code) +{ + if (!ts->font_size) { + ts->font_size = _fnl_get_actual_font_size(ts->font_type, ts->size); + } + return _fnl_size_char(ts->font_size, code); +} + +float fnl_size_text(struct text_style *ts, char *text) +{ + if (!ts->font_size) { + ts->font_size = _fnl_get_actual_font_size(ts->font_type, ts->size); } - return ((float)width / (float)ts->font_size->denominator) * ts->scale_x; -} - -void free_textures(void *data) -{ - struct fnl_glyph_texture *textures = data; - gfx_delete_texture(&textures[FONT_TEXTURE].t); - gfx_delete_texture(&textures[EDGE_TEXTURE].t); - free(textures); -} - -void fnl_renderer_free(struct fnl *fnl) -{ - fnl_free(fnl, free_textures); + float size = 0.0; + int len = sjis_count_char(text); + for (int i = 0; i < len; i++) { + size += _fnl_size_char(ts->font_size, sjis_code(text)); + text = sjis_skip_char(text); + } + return size; } diff --git a/src/hll/SengokuRanceFont.c b/src/hll/SengokuRanceFont.c index 928a9e7..4c5bc7c 100644 --- a/src/hll/SengokuRanceFont.c +++ b/src/hll/SengokuRanceFont.c @@ -31,8 +31,6 @@ #include "hll.h" #include "xsystem4.h" -static struct fnl *fontlib; - struct sr_text_properties { float x; int y; @@ -93,34 +91,18 @@ static void free_sp_properties(int sp_no) slot->value = NULL; } -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 void text_style_update(struct text_style *style) -{ - style->font_size = fnl_get_font_size(&fontlib->fonts[style->font_type], style->size); -} - //static void SengokuRanceFont_AlphaComposite(int spriteNumberDest, int destX, int destY, int spriteNumberSrc, int srcX, int srcY, int w, int h); static void SengokuRanceFont_SetFontType(int type) { - current_text_properties.ts.font_type = get_font_type(type); - text_style_update(¤t_text_properties.ts); + current_text_properties.ts.font_type = type; + current_text_properties.ts.font_size = NULL; } static void SengokuRanceFont_SetFontSize(float size) { current_text_properties.ts.size = size; - text_style_update(¤t_text_properties.ts); + current_text_properties.ts.font_size = NULL; } static void SengokuRanceFont_SetFontColor(int r, int g, int b) @@ -145,7 +127,7 @@ static void SengokuRanceFont_SetEdgeWidth(float w) static float SengokuRanceFont_GetTextWidth(struct string *str) { - return fnl_size_text(fontlib, ¤t_text_properties.ts, str->text); + return fnl_size_text(¤t_text_properties.ts, str->text); } //static float SengokuRanceFont_GetCharacterWidth(int charCode); @@ -298,7 +280,7 @@ static void SengokuRanceFont_SP_TextNewLine(int sp_no, float font_size) static void SengokuRanceFont_SP_SetTextMetricsClassic(int sp_no, struct page *page) { struct text_style *ts = &get_sp_properties(sp_no)->ts; - ts->font_type = get_font_type(256); + ts->font_type = 256; ts->color.r = page->values[0].i; ts->color.g = page->values[1].i; ts->color.b = page->values[2].i; @@ -315,13 +297,13 @@ static void SengokuRanceFont_SP_SetTextMetricsClassic(int sp_no, struct page *pa 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); + ts->font_size = NULL; } static void SengokuRanceFont_SP_SetTextStyle(int sp_no, struct page *page) { struct text_style *ts = &get_sp_properties(sp_no)->ts; - ts->font_type = get_font_type(page->values[0].i < 0 ? 256 : page->values[0].i); + ts->font_type = 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 & 0xFF; @@ -336,27 +318,20 @@ static void SengokuRanceFont_SP_SetTextStyle(int sp_no, struct page *page) ts->edge_color.a = 255; ts->scale_x = page->values[10].f < 0.0 ? 1.0 : page->values[10].f; ts->space_scale_x = page->values[11].f < 0.0 ? 1.0 : page->values[11].f; - ts->font_spacing = page->values[12].f < 0.0 ? 1.0 : page->values[12].f; - ts->font_size = fnl_get_font_size(&fontlib->fonts[ts->font_type], ts->size); + ts->font_spacing = page->values[12].f; + ts->font_size = NULL; } static float sp_text_draw(struct sact_sprite *sp, struct text_style *ts, struct string *text, float x, int y) { - // 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); - } struct texture *tex = sprite_get_texture(sp); sprite_dirty(sp); - return x + fnl_draw_text(fontlib, ts, tex, x, y, text->text); + return x + fnl_draw_text(ts, tex, x, y, text->text); } static void SengokuRanceFont_SP_TextDraw(int sp_no, struct string *text) @@ -392,14 +367,14 @@ static void SengokuRanceFont_SP_SetFontSize(int sp_no, float font_size) { struct text_style *ts = &get_sp_properties(sp_no)->ts; ts->size = font_size; - ts->font_size = fnl_get_font_size(&fontlib->fonts[ts->font_type], ts->size); + ts->font_size = NULL; } static void SengokuRanceFont_SP_SetFontType(int sp_no, int type) { struct text_style *ts = &get_sp_properties(sp_no)->ts; - ts->font_type = get_font_type(type); - text_style_update(ts); + ts->font_type = type; + ts->font_size = NULL; } static void SengokuRanceFont_SP_SetFontColor(int sp_no, int r, int g, int b) @@ -480,14 +455,12 @@ static float SengokuRanceFont_SP_GetSpaceScaleX(int sp_no) static float SengokuRanceFont_GetActualFontSize(int font_type, float font_size) { - font_type = get_font_type(font_type); - return fnl_get_font_size(&fontlib->fonts[font_type], font_size)->size; + return fnl_get_actual_font_size(font_type, font_size); } static float SengokuRanceFont_GetActualFontSizeRoundDown(int font_type, float font_size) { - font_type = get_font_type(font_type); - return fnl_get_font_size_round_down(&fontlib->fonts[font_type], font_size)->size; + return fnl_get_actual_font_size_round_down(font_type, font_size); } //static int SengokuRanceFont_SP_GetTextLastCharCode(int spriteNumber); @@ -520,22 +493,18 @@ static void SengokuRanceFont_ModuleInit(void) snprintf(path, PATH_MAX, "%s/%s", config.game_dir, d_name); free(d_name); - if (!(fontlib = fnl_open(path))) - ERROR("Error opening font library '%s'", display_utf0(path)); - if (fontlib->nr_fonts < 1) - ERROR("Font library doesn't contain any fonts"); + fnl_renderer_init(path); break; } closedir_utf8(dir); current_text_properties = default_text_properties; - text_style_update(¤t_text_properties.ts); } static void SengokuRanceFont_ModuleFini(void) { - fnl_renderer_free(fontlib); + fnl_renderer_fini(); } HLL_LIBRARY(SengokuRanceFont, diff --git a/subprojects/libsys4 b/subprojects/libsys4 index 7a7a378..7ca4b3b 160000 --- a/subprojects/libsys4 +++ b/subprojects/libsys4 @@ -1 +1 @@ -Subproject commit 7a7a378e072259bcb5734d84c1d935f66dc7c79b +Subproject commit 7ca4b3bbc760c7bb432b3513205961e1af8f1039