Rewrite fnl font renderer

Only unscaled glyph bitmaps are now cached in regular memory. Scaled
glyphs are stored as textures on the GPU. Only the alpha channel on
glyph textures is used, with the color being provided as an input to the
shader.

Outline and bold rendering is improved by using a simple dilate shader.
This looks okay but could be improved (the result is a bit blurry
still).
This commit is contained in:
Nunuhara Cabbage
2022-04-28 19:13:27 -07:00
parent 8fb0153963
commit 9089fa1fd1
6 changed files with 372 additions and 136 deletions
+10 -6
View File
@@ -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 */
+47
View File
@@ -0,0 +1,47 @@
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
*
* 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 <http://gnu.org/licenses/>.
*/
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));
}
+26
View File
@@ -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();
}
+271 -81
View File
@@ -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;
}
+17 -48
View File
@@ -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(&current_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(&current_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, &current_text_properties.ts, str->text);
return fnl_size_text(&current_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(&current_text_properties.ts);
}
static void SengokuRanceFont_ModuleFini(void)
{
fnl_renderer_free(fontlib);
fnl_renderer_fini();
}
HLL_LIBRARY(SengokuRanceFont,