evas/cserve2: Fix font hinting

cserve2 was not handling font hints properly in the server side
Add some consistency checks and separate glyphs per hinting value
This commit is contained in:
Jean-Philippe Andre 2013-09-02 16:17:05 +09:00
parent a7b3f7efd3
commit 808c20f989
5 changed files with 57 additions and 20 deletions

View File

@ -73,7 +73,7 @@ struct _Font_Entry {
unsigned int font_data_id;
Font_Source *src;
void *ft; // Font_Info
Fash_Glyph2 *glyph_entries; // Fast access to the Glyph_Entry objects
Fash_Glyph2 *glyph_entries[3]; // Fast access to the Glyph_Entry objects
Shared_Array *glyph_datas; // Contains the Glyph_Data objects
unsigned int nglyphs;
Eina_Bool unused : 1;
@ -1130,7 +1130,7 @@ static void
_font_entry_free(Font_Entry *fe)
{
Font_Data *fd;
int size;
int size, k;
if (!fe) return;
size = _font_entry_memory_usage_get(fe);
@ -1148,7 +1148,8 @@ _font_entry_free(Font_Entry *fe)
cserve2_shared_string_del(fd->name);
}
fash_gl_free(fe->glyph_entries);
for (k = 0; k < 3; k++)
fash_gl_free(fe->glyph_entries[k]);
cserve2_shared_array_del(fe->glyph_datas);
cserve2_shared_mempool_del(fe->mempool);
cserve2_font_ft_free(fe->ft);
@ -1720,16 +1721,23 @@ static Slave_Request_Funcs _font_load_funcs = {
static Eina_Bool
_glyphs_request_check(Glyphs_Request *req, Eina_Bool report_load)
{
unsigned int i;
unsigned int i, hint;
Font_Entry *fe = req->fe;
req->answer = malloc(sizeof(*req->answer) * req->nglyphs);
req->nanswer = 0;
hint = req->hint;
if (hint > 2)
{
WRN("Invalid font hint requested. Defaulting to 0.");
hint = 0;
}
for (i = req->current; i < req->nglyphs; i++)
{
Glyph_Entry *ge;
ge = fash_gl_find(fe->glyph_entries, req->glyphs[i]);
ge = fash_gl_find(fe->glyph_entries[hint], req->glyphs[i]);
if (ge)
{
req->answer[req->nanswer++] = ge;
@ -1767,7 +1775,7 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
size = sizeof(Msg_Font_Glyphs_Loaded);
size += sizeof(int) * 2;
size += shmname_size;
size += req->nanswer * 9 * sizeof(int);
size += req->nanswer * 10 * sizeof(int);
response = malloc(size);
if (!response) return NULL;
@ -1813,6 +1821,8 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
buf += sizeof(int);
memcpy(buf, &gldata->pixel_mode, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gldata->hint, sizeof(int));
buf += sizeof(int);
}
*resp_size = size;
@ -1915,7 +1925,7 @@ _glyphs_request_free(Glyphs_Request *req)
static void
_glyphs_load_request_prepare(Glyphs_Request *req)
{
unsigned int i, max;
unsigned int i, max, hint;
req->nrender = 0;
Font_Entry *fe = req->fe;
@ -1925,6 +1935,13 @@ _glyphs_load_request_prepare(Glyphs_Request *req)
return;
}
hint = req->hint;
if (hint > 2)
{
WRN("Invalid font hint requested. Defaulting to 0.");
hint = 0;
}
// Won't render more than this number of glyphs
max = req->nglyphs - req->nanswer;
req->render = malloc(sizeof(*req->render) * max);
@ -1932,7 +1949,7 @@ _glyphs_load_request_prepare(Glyphs_Request *req)
for (i = req->current; i < req->nglyphs; i++)
{
Glyph_Entry *ge;
ge = fash_gl_find(fe->glyph_entries, req->glyphs[i]);
ge = fash_gl_find(fe->glyph_entries[hint], req->glyphs[i]);
if (ge)
{
req->answer[req->nanswer++] = ge;
@ -1987,13 +2004,20 @@ _glyphs_load_request_response(Glyphs_Request *req,
{
Font_Entry *fe = req->fe;
Shared_Mempool *mempool = msg->mempool;
unsigned int j;
unsigned int j, hint;
string_t shm_id = 0;
Font_Data *fd;
if (!msg->nglyphs)
return _glyphs_loaded_msg_create(req, size);
hint = req->hint;
if (hint > 2)
{
WRN("Invalid font hint requested. Defaulting to 0.");
hint = 0;
}
fd = _font_data_find(fe->font_data_id);
DBG("Font memory usage [begin]: %d / %d", font_mem_usage, max_font_usage);
@ -2022,7 +2046,7 @@ _glyphs_load_request_response(Glyphs_Request *req,
{
Glyph_Entry *gl;
gl = fash_gl_find(fe->glyph_entries, msg->glyphs[j].index);
gl = fash_gl_find(fe->glyph_entries[hint], msg->glyphs[j].index);
if (!gl)
{
int glyph_id, orig_mapsize, new_mapsize;
@ -2056,9 +2080,10 @@ _glyphs_load_request_response(Glyphs_Request *req,
gldata->pitch = msg->glyphs[j].pitch;
gldata->num_grays = msg->glyphs[j].num_grays;
gldata->pixel_mode = msg->glyphs[j].pixel_mode;
gldata->hint = hint;
fe->nglyphs++;
fash_gl_add(fe->glyph_entries, gldata->index, gl);
fash_gl_add(fe->glyph_entries[hint], gldata->index, gl);
new_mapsize = cserve2_shared_array_map_size_get(fe->glyph_datas);
font_mem_usage += new_mapsize - orig_mapsize;
@ -2845,6 +2870,7 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name,
Font_Entry *fe;
char *fullname;
int fd_index;
int k;
if (source && !*source)
source = NULL;
@ -2879,7 +2905,8 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name,
fe->size = size;
fe->dpi = dpi;
fe->base.type = CSERVE2_FONT_ENTRY;
fe->glyph_entries = fash_gl_new(_glyph_free_cb);
for (k = 0; k < 3; k++)
fe->glyph_entries[k] = fash_gl_new(_glyph_free_cb);
ref = _entry_reference_add((Entry *)fe, client, 0);
client->fonts.referencing = eina_list_append(client->fonts.referencing, ref);
fe->unused = EINA_FALSE;

View File

@ -300,10 +300,10 @@ _glyph_data_print(Glyph_Data *gd)
"FT_PIXEL_MODE_LCD_V"
};
printf(" GLYPH id: %-4u refcount %-2u: index: %-6u offset: %-6u size: %-3u "
"%2ux%-3u pitch: %-2u grays: %-3u pixel mode: %s\n",
"%2ux%-3u pitch: %-2u grays: %-3u pixel mode: %s hint: %d\n",
gd->id, gd->refcount, gd->index, gd->offset, gd->size,
gd->width, gd->rows, gd->pitch,
gd->num_grays, pxmode[gd->pixel_mode]);
gd->num_grays, pxmode[gd->pixel_mode], gd->hint);
}
static void

View File

@ -586,7 +586,7 @@ _glyphs_all_print(Shm_File *sf)
int nglyphs = 0;
int mem_used = 0;
printf(" GlyphID Refcnt Index Size Rows Width Pitch Grays Mode "
printf(" GlyphID Refcnt Index Size Rows Width Pitch Grays H M "
"BufID Offset ShmPath\n");
for (k = 0; k < sf->header->count; k++)
@ -597,9 +597,9 @@ _glyphs_all_print(Shm_File *sf)
if (!gd) break;
if (!gd->id) continue;
printf(" %8u %6u %6u %5u %5u %5u %5u %5u %5u %6u %6u '%s'\n",
printf(" %8u %6u %6u %5u %5u %5u %5u %5u %1u %1u %6u %6u '%s'\n",
gd->id, gd->refcount, gd->index, gd->size, gd->rows, gd->width,
gd->pitch, gd->num_grays, gd->pixel_mode, gd->buffer_id,
gd->pitch, gd->num_grays, gd->hint, gd->pixel_mode, gd->buffer_id,
gd->offset, _shared_string_get(gd->shm_id));
nglyphs++;
@ -621,7 +621,8 @@ _fonts_all_print_full(void)
printf("List of loaded fonts: %s\n", eina_file_filename_get(sf_fonts->f));
printf("Rendering flags: "
"R: Regular, S: Slanted, W: Weight, X: Invalid\n\n");
"R: Regular, S: Slanted, W: Weight, X: Invalid\n");
printf("H: Hint, M: Pixel mode\n\n");
printf_newline(0);
for (k = 0; k < sf_fonts->header->count; k++)

View File

@ -373,6 +373,7 @@ struct _Glyph_Data {
uint32_t pitch;
uint32_t num_grays;
uint32_t pixel_mode;
uint32_t hint;
};
struct _Msg_Error {

View File

@ -1434,6 +1434,7 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints)
gd = &(fe->map->index.entries.gldata[k]);
if (!gd->id) break;
if (!gd->refcount) continue;
if (gd->hint != hints) continue;
tot++;
gl = fash_gl_find(fe->fash[hints], gd->index);
@ -1523,7 +1524,7 @@ _glyph_request_cb(void *data, const void *msg, int size)
for (i = 0; i < nglyphs; i++)
{
string_t shm_id;
unsigned int idx, offset, glsize;
unsigned int idx, offset, glsize, hints;
int rows, width, pitch, num_grays, pixel_mode;
CS_Glyph_Out *gl;
@ -1549,8 +1550,15 @@ _glyph_request_cb(void *data, const void *msg, int size)
buf += sizeof(int);
memcpy(&pixel_mode, buf, sizeof(int));
buf += sizeof(int);
memcpy(&hints, buf, sizeof(int));
buf += sizeof(int);
if (hints != grd->hints)
{
WRN("Invalid hints received: %d vs %d. Skip.", hints, grd->hints);
continue;
}
gl = fash_gl_find(fe->fash[grd->hints], idx);
gl = fash_gl_find(fe->fash[hints], idx);
if (gl)
{
gl->map = fe->map;