jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=808c20f9896d4a92f15a653dd23d7e9088ab84d6
commit 808c20f9896d4a92f15a653dd23d7e9088ab84d6 Author: Jean-Philippe Andre <[email protected]> Date: Mon Sep 2 16:17:05 2013 +0900 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 --- src/bin/evas/evas_cserve2_cache.c | 51 ++++++++++++++++++++++++++-------- src/bin/evas/evas_cserve2_debug.c | 4 +-- src/bin/evas/evas_cserve2_shm_debug.c | 9 +++--- src/lib/evas/cserve2/evas_cs2.h | 1 + src/lib/evas/cserve2/evas_cs2_client.c | 12 ++++++-- 5 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/bin/evas/evas_cserve2_cache.c b/src/bin/evas/evas_cserve2_cache.c index b71ce01..40cd55d 100644 --- a/src/bin/evas/evas_cserve2_cache.c +++ b/src/bin/evas/evas_cserve2_cache.c @@ -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; diff --git a/src/bin/evas/evas_cserve2_debug.c b/src/bin/evas/evas_cserve2_debug.c index 7eaea5d..92c8c88 100644 --- a/src/bin/evas/evas_cserve2_debug.c +++ b/src/bin/evas/evas_cserve2_debug.c @@ -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 diff --git a/src/bin/evas/evas_cserve2_shm_debug.c b/src/bin/evas/evas_cserve2_shm_debug.c index bde62bd..426fd67 100644 --- a/src/bin/evas/evas_cserve2_shm_debug.c +++ b/src/bin/evas/evas_cserve2_shm_debug.c @@ -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++) diff --git a/src/lib/evas/cserve2/evas_cs2.h b/src/lib/evas/cserve2/evas_cs2.h index bcba89a..a47c384 100644 --- a/src/lib/evas/cserve2/evas_cs2.h +++ b/src/lib/evas/cserve2/evas_cs2.h @@ -373,6 +373,7 @@ struct _Glyph_Data { uint32_t pitch; uint32_t num_grays; uint32_t pixel_mode; + uint32_t hint; }; struct _Msg_Error { diff --git a/src/lib/evas/cserve2/evas_cs2_client.c b/src/lib/evas/cserve2/evas_cs2_client.c index 1538b49..e32dc1d 100644 --- a/src/lib/evas/cserve2/evas_cs2_client.c +++ b/src/lib/evas/cserve2/evas_cs2_client.c @@ -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; --
