efl/legacy/evas/src/bin/evas_cserve2_fonts.c

212 lines
4.6 KiB
C

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_SIZES_H
#include FT_MODULE_H
#include "evas_cserve2.h"
static FT_Library cserve2_ft_lib = 0;
static int initialised = 0;
struct _Font_Info
{
FT_Size size;
int real_size;
int max_h;
unsigned int runtime_rend;
};
struct _Font_Source_Info
{
FT_Face face;
int orig_upem;
int current_size;
};
typedef struct _Font_Info Font_Info;
typedef struct _Font_Source_Info Font_Source_Info;
static Font_Source_Info *
_font_slave_source_load(const char *file)
{
int error;
Font_Source_Info *fsi = malloc(sizeof(*fsi));
error = FT_New_Face(cserve2_ft_lib, file, 0, &(fsi->face));
if (error)
{
free(fsi);
return NULL;
}
error = FT_Select_Charmap(fsi->face, ft_encoding_unicode);
if (error)
{
FT_Done_Face(fsi->face);
free(fsi);
return NULL;
}
fsi->orig_upem = fsi->face->units_per_EM;
fsi->current_size = 0;
return fsi;
}
static Font_Info *
_font_slave_int_load(const Slave_Msg_Font_Load *msg, Font_Source_Info *fsi)
{
int error;
int val, dv;
int ret;
Font_Info *fi = calloc(1, sizeof(*fi));
error = FT_New_Size(fsi->face, &(fi->size));
if (!error)
FT_Activate_Size(fi->size);
fi->real_size = msg->size * 64;
error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, msg->dpi, msg->dpi);
if (error)
{
fi->real_size = msg->size;
error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);
}
if (error)
{
int i;
int chosen_size = 0;
int chosen_width = 0;
for (i = 0; i < fsi->face->num_fixed_sizes; i++)
{
int s;
int d, cd;
s = fsi->face->available_sizes[i].height;
cd = chosen_size - msg->size;
if (cd < 0) cd = -cd;
d = s - msg->size;
if (d < 0) d = -d;
if (d < cd)
{
chosen_width = fsi->face->available_sizes[i].width;
chosen_size = s;
}
if (d == 0) break;
}
fi->real_size = chosen_size;
error = FT_Set_Pixel_Sizes(fsi->face, chosen_width, fi->real_size);
if (error)
ERR("Could not choose the font size.");
}
fi->max_h = 0;
val = (int)fsi->face->bbox.yMax;
if (fsi->face->units_per_EM != 0)
{
dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM;
ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv);
}
else ret = val;
fi->max_h += ret;
val = -(int)fsi->face->bbox.yMin;
if (fsi->face->units_per_EM != 0)
{
dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM;
ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv);
}
else ret = val;
fi->max_h += ret;
fi->runtime_rend = FONT_REND_REGULAR;
if ((msg->rend_flags & FONT_REND_SLANT) &&
!(fsi->face->style_flags & FT_STYLE_FLAG_ITALIC))
fi->runtime_rend |= FONT_REND_SLANT;
if ((msg->rend_flags & FONT_REND_WEIGHT) &&
!(fsi->face->style_flags & FT_STYLE_FLAG_BOLD))
fi->runtime_rend |= FONT_REND_WEIGHT;
return fi;
}
static Slave_Msg_Font_Loaded *
_font_slave_load(const void *cmddata, void *data __UNUSED__)
{
const Slave_Msg_Font_Load *msg = cmddata;
Slave_Msg_Font_Loaded *response;
Font_Source_Info *fsi;
Font_Info *fi;
fsi = msg->ftdata1;
/* Loading Font Source */
if (!fsi)
fsi = _font_slave_source_load(msg->file);
// FIXME: Return correct error message
if (!fsi)
return NULL;
fi = _font_slave_int_load(msg, fsi);
response = calloc(1, sizeof(*response));
response->ftdata1 = fsi;
response->ftdata2 = fi;
return response;
}
void *
cserve2_font_slave_cb(Slave_Thread_Data *sd __UNUSED__, Slave_Command cmd, const void *cmddata, void *data)
{
void *response = NULL;
switch (cmd)
{
case FONT_LOAD:
_font_slave_load(cmddata, data);
break;
case FONT_GLYPHS_LOAD:
// command for FONT_GLYPHS_LOAD
break;
default:
ERR("Invalid command for font slave: %d", cmd);
}
return response;
}
void
cserve2_font_init(void)
{
int error;
if (initialised++ > 0) return;
error = FT_Init_FreeType(&cserve2_ft_lib);
if (error) return;
}
void
cserve2_font_shutdown(void)
{
initialised--;
if (initialised > 0) return;
if (initialised < 0)
{
ERR("Invalid shutdown of cserve2 font.");
return;
}
FT_Done_FreeType(cserve2_ft_lib);
cserve2_ft_lib = 0;
}