diff --git a/legacy/evas/src/lib/canvas/evas_font_dir.c b/legacy/evas/src/lib/canvas/evas_font_dir.c index e97f7f7414..aa0d9c3299 100644 --- a/legacy/evas/src/lib/canvas/evas_font_dir.c +++ b/legacy/evas/src/lib/canvas/evas_font_dir.c @@ -588,7 +588,7 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva fdata = eet_read(ef, nm, &fsize); if ((fdata) && (fsize > 0)) { - font = evas->engine.func->font_memory_load(evas->engine.data.output, fake_name, size, fdata, fsize, wanted_rend); + font = evas->engine.func->font_memory_load(evas->engine.data.output, source, nm, size, fdata, fsize, wanted_rend); free(fdata); } eet_close(ef); @@ -649,7 +649,7 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva fdata = eet_read(ef, nm, &fsize); if ((fdata) && (fsize > 0)) { - ok = evas->engine.func->font_memory_add(evas->engine.data.output, font, fake_name, size, fdata, fsize, wanted_rend); + ok = evas->engine.func->font_memory_add(evas->engine.data.output, font, source, nm, size, fdata, fsize, wanted_rend); free(fdata); } eet_close(ef); diff --git a/legacy/evas/src/lib/cserve2/evas_cs2_client.c b/legacy/evas/src/lib/cserve2/evas_cs2_client.c index 1b93ccdddf..ddf0186bbc 100644 --- a/legacy/evas/src/lib/cserve2/evas_cs2_client.c +++ b/legacy/evas/src/lib/cserve2/evas_cs2_client.c @@ -12,6 +12,7 @@ #include "evas_cs2.h" #include "evas_cs2_private.h" +#include "evas_cs2_utils.h" #ifdef EVAS_CSERVE2 @@ -129,16 +130,38 @@ _request_answer_add(Message_Type type, unsigned int rid, Op_Callback cb, void *d _requests = eina_list_append(_requests, cr); } +static Eina_Bool +_server_safe_send(int fd, const void *data, int size) +{ + int sent = 0; + ssize_t ret; + const char *msg = data; + + while (sent < size) + { + ret = send(fd, msg + sent, size - sent, MSG_NOSIGNAL); + if (ret < 0) + { + if ((errno == EAGAIN) || (errno == EINTR)) + continue; + return EINA_FALSE; + } + sent += ret; + } + + return EINA_TRUE; +} + static Eina_Bool _server_send(const void *buf, int size, Op_Callback cb, void *data) { const Msg_Base *msg; - if (send(socketfd, &size, sizeof(size), MSG_NOSIGNAL) == -1) + if (_server_safe_send(socketfd, &size, sizeof(size)) == -1) { ERR("Couldn't send message size to server."); return EINA_FALSE; } - if (send(socketfd, buf, size, MSG_NOSIGNAL) == -1) + if (_server_safe_send(socketfd, buf, size) == -1) { ERR("Couldn't send message body to server."); return EINA_FALSE; @@ -151,6 +174,8 @@ _server_send(const void *buf, int size, Op_Callback cb, void *data) case CSERVE2_SETOPTS: case CSERVE2_LOAD: case CSERVE2_PRELOAD: + case CSERVE2_FONT_LOAD: + case CSERVE2_FONT_GLYPHS_LOAD: _request_answer_add(msg->type, msg->rid, cb, data); break; default: @@ -752,4 +777,507 @@ evas_cserve2_dispatch(void) { _server_dispatch_until(0); } + +typedef struct _Glyph_Map Glyph_Map; +typedef struct _CS_Glyph_Out CS_Glyph_Out; + +struct _Font_Entry +{ + const char *source; + const char *name; + unsigned int size; + unsigned int dpi; + Font_Rend_Flags wanted_rend; + + unsigned int rid; // open + + Eina_Hash *glyphs_maps; + Fash_Glyph *fash[3]; // one per hinting value + + Eina_Clist glyphs_queue; + int glyphs_queue_count; + Eina_Clist glyphs_used; + int glyphs_used_count; + + Eina_Bool failed : 1; +}; + +struct _Glyph_Map +{ + Font_Entry *fe; + const char *name; + unsigned int size; + Eina_File *map; + unsigned char *data; + Eina_Clist glyphs; +}; + +struct _CS_Glyph_Out +{ + RGBA_Font_Glyph_Out base; + Eina_Clist map_entry; + Eina_Clist used_list; + unsigned int idx; + unsigned int rid; + Glyph_Map *map; + unsigned int offset; + unsigned int size; + Eina_Bool used; +}; + +static void +_font_entry_free(Font_Entry *fe) +{ + int i; + + for (i = 0; i < 3; i++) + if (fe->fash[i]) + fash_gl_free(fe->fash[i]); + + eina_stringshare_del(fe->source); + eina_stringshare_del(fe->name); + eina_hash_free(fe->glyphs_maps); + free(fe); +} + +static void +_glyphs_map_free(Glyph_Map *m) +{ + eina_file_map_free(m->map, m->data); + eina_file_close(m->map); + eina_stringshare_del(m->name); + free(m); +} + +static void +_glyph_out_free(void *gl) +{ + CS_Glyph_Out *glout = gl; + + if (glout->map) + { + eina_clist_remove(&glout->map_entry); + if (eina_clist_empty(&glout->map->glyphs)) + { + eina_hash_del(glout->map->fe->glyphs_maps, &glout->map->name, + NULL); + _glyphs_map_free(glout->map); + } + } + + free(glout); +} + +static void +_font_loaded_cb(void *data, const void *msg) +{ + const Msg_Base *m = msg; + Font_Entry *fe = data; + + fe->rid = 0; + + if (m->type == CSERVE2_ERROR) + fe->failed = EINA_TRUE; +} + +static unsigned int +_font_load_server_send(Font_Entry *fe, Message_Type type) +{ + Msg_Font_Load *msg; + int source_len, path_len, size; + char *buf; + unsigned int ret = 0; + void (*cb)(void *data, const void *msg) = NULL; + + if (!cserve2_init) + return 0; + + source_len = fe->source ? eina_stringshare_strlen(fe->source) + 1 : 0; + path_len = eina_stringshare_strlen(fe->name) + 1; + + size = sizeof(*msg) + path_len + source_len; + msg = calloc(1, size); + + msg->base.rid = _next_rid(); + msg->base.type = type; + + msg->sourcelen = source_len; + msg->pathlen = path_len; + msg->rend_flags = fe->wanted_rend; + msg->size = fe->size; + msg->dpi = fe->dpi; + + buf = ((char *)msg) + sizeof(*msg); + memcpy(buf, fe->source, source_len); + buf += source_len; + memcpy(buf, fe->name, path_len); + + if (type == CSERVE2_FONT_LOAD) + cb = _font_loaded_cb; + + if (_server_send(msg, size, cb, fe)) + ret = msg->base.rid; + + free(msg); + + return ret; +} + +Font_Entry * +evas_cserve2_font_load(const char *source, const char *name, int size, int dpi, Font_Rend_Flags wanted_rend) +{ + Font_Entry *fe; + + fe = calloc(1, sizeof(Font_Entry)); + if (!fe) return NULL; + + fe->source = source ? eina_stringshare_add(source) : NULL; + fe->name = eina_stringshare_add(name); + fe->size = size; + fe->dpi = dpi; + fe->wanted_rend = wanted_rend; + + if (!(fe->rid = _font_load_server_send(fe, CSERVE2_FONT_LOAD))) + { + eina_stringshare_del(fe->source); + eina_stringshare_del(fe->name); + free(fe); + return NULL; + } + + fe->glyphs_maps = eina_hash_stringshared_new(NULL); + eina_clist_init(&fe->glyphs_queue); + eina_clist_init(&fe->glyphs_used); + + return fe; +} + +void +evas_cserve2_font_free(Font_Entry *fe) +{ + if (!fe) return; + + if (fe->failed) + return; + + _font_load_server_send(fe, CSERVE2_FONT_UNLOAD); + + _font_entry_free(fe); +} + +typedef struct +{ + Font_Entry *fe; + Font_Hint_Flags hints; + unsigned int rid; +} Glyph_Request_Data; + +static void +_glyph_request_cb(void *data, const void *msg) +{ + const Msg_Font_Glyphs_Loaded *resp = msg; + Glyph_Request_Data *grd = data; + Font_Entry *fe = grd->fe; + int ncaches = 0; + const char *buf; + + if (resp->base.type == CSERVE2_ERROR) + { + free(grd); + return; + } + + buf = (const char *)resp + sizeof(*resp); + while (ncaches < resp->ncaches) + { + int i = 0, nglyphs; + int namelen; + const char *name; + Glyph_Map *map; + + memcpy(&namelen, buf, sizeof(int)); + buf += sizeof(int); + + name = eina_stringshare_add_length(buf, namelen); + buf += namelen; + + memcpy(&nglyphs, buf, sizeof(int)); + buf += sizeof(int); + + map = eina_hash_find(fe->glyphs_maps, name); + if (!map) + { + map = calloc(1, sizeof(*map)); + map->fe = fe; + map->name = name; + map->map = eina_file_open(name, EINA_TRUE); + map->data = eina_file_map_all(map->map, EINA_FILE_WILLNEED); + eina_clist_init(&map->glyphs); + eina_hash_direct_add(fe->glyphs_maps, &map->name, map); + } + else + eina_stringshare_del(name); + + while (i < nglyphs) + { + unsigned int idx, offset, glsize; + int rows, width, pitch, num_grays, pixel_mode; + CS_Glyph_Out *gl; + + memcpy(&idx, buf, sizeof(int)); + buf += sizeof(int); + memcpy(&offset, buf, sizeof(int)); + buf += sizeof(int); + memcpy(&glsize, buf, sizeof(int)); + buf += sizeof(int); + memcpy(&rows, buf, sizeof(int)); + buf += sizeof(int); + memcpy(&width, buf, sizeof(int)); + buf += sizeof(int); + memcpy(&pitch, buf, sizeof(int)); + buf += sizeof(int); + memcpy(&num_grays, buf, sizeof(int)); + buf += sizeof(int); + memcpy(&pixel_mode, buf, sizeof(int)); + buf += sizeof(int); + + gl = fash_gl_find(fe->fash[grd->hints], idx); + gl->map = map; + gl->offset = offset; + gl->size = glsize; + gl->base.bitmap.rows = rows; + gl->base.bitmap.width = width; + gl->base.bitmap.pitch = pitch; + gl->base.bitmap.buffer = map->data + gl->offset; + gl->base.bitmap.num_grays = num_grays; + gl->base.bitmap.pixel_mode = pixel_mode; + + gl->rid = 0; + + eina_clist_add_head(&map->glyphs, &gl->map_entry); + + i++; + } + + ncaches++; + } + + free(grd); +} + +static unsigned int +_glyph_request_server_send(Font_Entry *fe, Font_Hint_Flags hints, Eina_Bool used) +{ + Msg_Font_Glyphs_Request *msg; + Glyph_Request_Data *grd = NULL; + int source_len, name_len, size, nglyphs; + char *buf; + unsigned int *glyphs; + unsigned int ret = 0; + Op_Callback cb; + Eina_Clist *queue, *itr, *itr_next; + + + source_len = fe->source ? eina_stringshare_strlen(fe->source) + 1 : 0; + name_len = eina_stringshare_strlen(fe->name) + 1; + + if (!used) + { + nglyphs = fe->glyphs_queue_count; + queue = &fe->glyphs_queue; + } + else + { + nglyphs = fe->glyphs_used_count; + queue = &fe->glyphs_used; + } + + size = sizeof(*msg) + source_len + name_len + (nglyphs * sizeof(int)); + msg = calloc(1, size); + + msg->base.rid = _next_rid(); + if (!used) + msg->base.type = CSERVE2_FONT_GLYPHS_LOAD; + else + msg->base.type = CSERVE2_FONT_GLYPHS_USED; + + msg->sourcelen = source_len; + msg->pathlen = name_len; + msg->rend_flags = fe->wanted_rend; + msg->size = fe->size; + msg->dpi = fe->dpi; + msg->hint = hints; + msg->nglyphs = nglyphs; + + buf = ((char *)msg) + sizeof(*msg); + memcpy(buf, fe->source, source_len); + buf += source_len; + memcpy(buf, fe->name, name_len); + buf += name_len; + glyphs = (unsigned int *)buf; + nglyphs = 0; + EINA_CLIST_FOR_EACH_SAFE(itr, itr_next, queue) + { + CS_Glyph_Out *gl; + + if (!used) + { + gl = EINA_CLIST_ENTRY(itr, CS_Glyph_Out, map_entry); + gl->rid = msg->base.rid; + eina_clist_remove(&gl->map_entry); + } + else + { + gl = EINA_CLIST_ENTRY(itr, CS_Glyph_Out, used_list); + gl->used = EINA_FALSE; + eina_clist_remove(&gl->used_list); + } + glyphs[nglyphs++] = gl->idx; + } + if (!used) + fe->glyphs_queue_count = 0; + else + fe->glyphs_used_count = 0; + + if (!used) + { + cb = _glyph_request_cb; + grd = malloc(sizeof(*grd)); + grd->fe = fe; + grd->rid = msg->base.rid; + grd->hints = hints; + } + else + cb = NULL; + + if (_server_send(msg, size, cb, grd)) + ret = msg->base.rid; + else + free(grd); + + free(msg); + + return ret; +} + +Eina_Bool +evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints) +{ + Fash_Glyph *fash; + CS_Glyph_Out *glyph; + + if (fe->rid) + _server_dispatch_until(fe->rid); + + if (fe->failed) + return EINA_FALSE; + + fash = fe->fash[hints]; + if (!fash) + { + fash = fash_gl_new(_glyph_out_free); + fe->fash[hints] = fash; + } + + glyph = fash_gl_find(fash, idx); + if (!glyph) + { + glyph = calloc(1, sizeof(*glyph)); + + glyph->idx = idx; + + fash_gl_add(fash, idx, glyph); + + eina_clist_add_head(&fe->glyphs_queue, &glyph->map_entry); + fe->glyphs_queue_count++; + } + else if (!glyph->used) + { + eina_clist_add_head(&fe->glyphs_used, &glyph->used_list); + fe->glyphs_used_count++; + glyph->used = EINA_TRUE; + } + + /* crude way to manage a queue, but it will work for now */ + if (fe->glyphs_queue_count == 50) + _glyph_request_server_send(fe, hints, EINA_FALSE); + + return EINA_TRUE; +} + +Eina_Bool +evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints) +{ + Fash_Glyph *fash; + CS_Glyph_Out *glyph; + + if (fe->rid) + _server_dispatch_until(fe->rid); + + if (fe->failed) + return EINA_FALSE; + + fash = fe->fash[hints]; + if (!fash) + return EINA_FALSE; + + glyph = fash_gl_find(fash, idx); + /* If we found the glyph on client cache, we should also have at least + * its request done. + */ + if (!glyph) + return EINA_FALSE; + + if (!glyph->map) + return EINA_TRUE; + + if (glyph->used) + return EINA_TRUE; + + eina_clist_add_head(&fe->glyphs_used, &glyph->used_list); + fe->glyphs_used_count++; + glyph->used = EINA_TRUE; + + return EINA_TRUE; +} + +RGBA_Font_Glyph_Out * +evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints) +{ + Fash_Glyph *fash; + CS_Glyph_Out *out; + + if (fe->failed) + return NULL; + + /* quick hack, flush pending queue when we are asked for a bitmap */ + if (fe->glyphs_queue_count) + _glyph_request_server_send(fe, hints, EINA_FALSE); + + if (fe->glyphs_used_count) + _glyph_request_server_send(fe, hints, EINA_TRUE); + + fash = fe->fash[hints]; + if (!fash) + { + // this should not happen really, so let the user know he fucked up + system("format c:"); + return NULL; + } + + out = fash_gl_find(fash, idx); + if (!out) + { + // again, if we are asking for a bitmap we were supposed to already + // have requested the glyph, it must be there + return NULL; + } + if (out->rid) + _server_dispatch_until(out->rid); + + // promote shm and font entry in lru or something + + return &(out->base); +} + #endif diff --git a/legacy/evas/src/lib/cserve2/evas_cs2_private.h b/legacy/evas/src/lib/cserve2/evas_cs2_private.h index c0dde77057..4373bfdab3 100644 --- a/legacy/evas/src/lib/cserve2/evas_cs2_private.h +++ b/legacy/evas/src/lib/cserve2/evas_cs2_private.h @@ -18,6 +18,7 @@ struct _Data_Entry { }; typedef struct _Data_Entry Data_Entry; +typedef struct _Font_Entry Font_Entry; int evas_cserve2_init(void); int evas_cserve2_shutdown(void); @@ -32,4 +33,10 @@ Eina_Bool evas_cserve2_image_preload(Image_Entry *ie, void (*preloaded_cb)(void void evas_cserve2_dispatch(void); void *evas_cserve2_image_data_get(Image_Entry *ie); + +Font_Entry *evas_cserve2_font_load(const char *source, const char *name, int size, int dpi, Font_Rend_Flags wanted_rend); +void evas_cserve2_font_free(Font_Entry *fe); +Eina_Bool evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints); +Eina_Bool evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints); +RGBA_Font_Glyph_Out *evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints); #endif diff --git a/legacy/evas/src/lib/engines/common/evas_font.h b/legacy/evas/src/lib/engines/common/evas_font.h index ed6655bef5..3769b13975 100644 --- a/legacy/evas/src/lib/engines/common/evas_font.h +++ b/legacy/evas/src/lib/engines/common/evas_font.h @@ -37,17 +37,17 @@ EAPI void evas_common_font_size_use (RGBA_Font *fn); EAPI RGBA_Font_Int *evas_common_font_int_load (const char *name, int size, Font_Rend_Flags wanted_rend); EAPI RGBA_Font_Int *evas_common_font_int_load_init (RGBA_Font_Int *fn); EAPI RGBA_Font_Int *evas_common_font_int_load_complete (RGBA_Font_Int *fi); -EAPI RGBA_Font *evas_common_font_memory_load (const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend); +EAPI RGBA_Font *evas_common_font_memory_load (const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend); EAPI RGBA_Font *evas_common_font_load (const char *name, int size, Font_Rend_Flags wanted_rend); EAPI RGBA_Font *evas_common_font_add (RGBA_Font *fn, const char *name, int size, Font_Rend_Flags wanted_rend); -EAPI RGBA_Font *evas_common_font_memory_add (RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend); +EAPI RGBA_Font *evas_common_font_memory_add (RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend); EAPI void evas_common_font_free (RGBA_Font *fn); EAPI void evas_common_font_hinting_set (RGBA_Font *fn, Font_Hint_Flags hinting); EAPI Eina_Bool evas_common_hinting_available (Font_Hint_Flags hinting); -EAPI RGBA_Font *evas_common_font_memory_hinting_load (const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend); +EAPI RGBA_Font *evas_common_font_memory_hinting_load (const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend); EAPI RGBA_Font *evas_common_font_hinting_load (const char *name, int size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend); EAPI RGBA_Font *evas_common_font_hinting_add (RGBA_Font *fn, const char *name, int size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend); -EAPI RGBA_Font *evas_common_font_memory_hinting_add (RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend); +EAPI RGBA_Font *evas_common_font_memory_hinting_add (RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend); EAPI void evas_common_font_int_modify_cache_by (RGBA_Font_Int *fi, int dir); EAPI int evas_common_font_cache_get (void); EAPI void evas_common_font_cache_set (int size); diff --git a/legacy/evas/src/lib/engines/common/evas_font_default_walk.x b/legacy/evas/src/lib/engines/common/evas_font_default_walk.x index f6e4520c4e..7636201160 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_default_walk.x +++ b/legacy/evas/src/lib/engines/common/evas_font_default_walk.x @@ -97,7 +97,7 @@ #define EVAS_FONT_WALK_IS_VISIBLE (_glyph_itr->index != 0) #define EVAS_FONT_WALK_X_BEAR (_glyph_itr->x_bear) -#define EVAS_FONT_WALK_Y_BEAR (fg->glyph_out->top) +#define EVAS_FONT_WALK_Y_BEAR (_glyph_itr->y_bear) #define EVAS_FONT_WALK_X_ADV ((_glyph_itr > text_props->info->glyph) ? \ _glyph_itr->pen_after - (_glyph_itr - 1)->pen_after : \ _glyph_itr->pen_after) diff --git a/legacy/evas/src/lib/engines/common/evas_font_draw.c b/legacy/evas/src/lib/engines/common/evas_font_draw.c index 614e56ebc5..5a5bb7eb7a 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -7,35 +7,6 @@ #include "evas_font_ot.h" -struct prword -{ - EINA_INLIST; - struct cinfo *cinfo; - Evas_Text_Props text_props; - DATA8 *im; - int roww; - int width; - int height; - int baseline; -}; - -struct cinfo -{ - FT_UInt index; - struct - { - int x, y; - } pos; - int posx; - RGBA_Font_Glyph *fg; - struct - { - int w,h; - int rows; - unsigned char *data; - } bm; -}; - typedef struct _Evas_Glyph Evas_Glyph; struct _Evas_Glyph { @@ -82,6 +53,11 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in fg = glyphs[it].fg; idx = glyphs[it].idx; + glyphs[it].coord.w = fg->glyph_out->bitmap.width; + glyphs[it].coord.h = fg->glyph_out->bitmap.rows; + glyphs[it].j = fg->glyph_out->bitmap.pitch; + glyphs[it].data = fg->glyph_out->bitmap.buffer; + if (dc->font_ext.func.gl_new) { /* extension calls */ @@ -102,11 +78,6 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in w = glyphs[it].coord.w; if (j < w) j = w; h = glyphs[it].coord.h; - /* - if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays) - && (fg->glyph_out->bitmap.num_grays == 256) - ) - */ #ifdef HAVE_PIXMAN # ifdef PIXMAN_FONT @@ -260,6 +231,7 @@ EAPI void evas_common_font_draw_prepare(Evas_Text_Props *text_props) { RGBA_Font_Int *fi; + RGBA_Font_Glyph *fg; EVAS_FONT_WALK_TEXT_INIT(); fi = text_props->font_instance; @@ -285,7 +257,6 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props) EVAS_FONT_WALK_TEXT_START() { Evas_Glyph glyph; - RGBA_Font_Glyph *fg; FT_UInt idx; if (!EVAS_FONT_WALK_IS_VISIBLE) continue; @@ -298,16 +269,16 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props) glyph.fg = fg; glyph.coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR; glyph.coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR; - glyph.coord.w = fg->glyph_out->bitmap.width; - glyph.coord.h = fg->glyph_out->bitmap.rows; - glyph.j = fg->glyph_out->bitmap.pitch; glyph.idx = idx; - glyph.data = fg->glyph_out->bitmap.buffer; eina_binbuf_append_length(text_props->bin, (void*) &glyph, sizeof (Evas_Glyph)); } EVAS_FONT_WALK_TEXT_END(); + /* check if there's a request queue in fi, if so ask cserve2 to render + * those glyphs + */ + text_props->generation = fi->generation; } diff --git a/legacy/evas/src/lib/engines/common/evas_font_load.c b/legacy/evas/src/lib/engines/common/evas_font_load.c index 8e0bc15ea6..2307fde8df 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_load.c +++ b/legacy/evas/src/lib/engines/common/evas_font_load.c @@ -6,6 +6,10 @@ #include "evas_font_private.h" /* for Frame-Queuing support */ #include "evas_font_ot.h" +#ifdef EVAS_CSERVE2 +# include "../../cserve2/evas_cs2_private.h" +#endif + #ifdef USE_HARFBUZZ # include # include @@ -85,6 +89,9 @@ _evas_common_font_int_free(RGBA_Font_Int *fi) fonts_use_usage -= fi->usage; fi->usage = 0; } +#ifdef EVAS_CSERVE2 + evas_cserve2_font_free(fi->cs2_handler); +#endif free(fi); } @@ -303,26 +310,43 @@ _evas_common_font_int_cache_init(RGBA_Font_Int *fi) } EAPI RGBA_Font_Int * -evas_common_font_int_memory_load(const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend) +evas_common_font_int_memory_load(const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend) { RGBA_Font_Int *fi; + char *fake_name; - fi = evas_common_font_int_find(name, size, wanted_rend); - if (fi) return fi; + fake_name = evas_file_path_join(source, name); + fi = evas_common_font_int_find(fake_name, size, wanted_rend); + if (fi) + { + free(fake_name); + return fi; + } fi = calloc(1, sizeof(RGBA_Font_Int)); - if (!fi) return NULL; - fi->src = evas_common_font_source_find(name); + if (!fi) + { + free(fake_name); + return NULL; + } + fi->src = evas_common_font_source_find(fake_name); if (!fi->src) - fi->src = evas_common_font_source_memory_load(name, data, data_size); + fi->src = evas_common_font_source_memory_load(fake_name, data, data_size); if (!fi->src) { free(fi); + free(fake_name); return NULL; } fi->size = size; _evas_common_font_int_cache_init(fi); fi = evas_common_font_int_load_init(fi); evas_common_font_int_load_complete(fi); +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + fi->cs2_handler = evas_cserve2_font_load(source, name, size, font_dpi, + wanted_rend); +#endif + free(fake_name); return fi; } @@ -349,6 +373,11 @@ evas_common_font_int_load(const char *name, int size, fi->wanted_rend = wanted_rend; _evas_common_font_int_cache_init(fi); fi = evas_common_font_int_load_init(fi); +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + fi->cs2_handler = evas_cserve2_font_load(NULL, name, size, font_dpi, + wanted_rend); +#endif // evas_common_font_int_load_complete(fi); return fi; } @@ -469,12 +498,12 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi) } EAPI RGBA_Font * -evas_common_font_memory_load(const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend) +evas_common_font_memory_load(const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend) { RGBA_Font *fn; RGBA_Font_Int *fi; - fi = evas_common_font_int_memory_load(name, size, data, data_size, + fi = evas_common_font_int_memory_load(source, name, size, data, data_size, wanted_rend); if (!fi) return NULL; fn = calloc(1, sizeof(RGBA_Font)); @@ -585,13 +614,13 @@ evas_common_font_add(RGBA_Font *fn, const char *name, int size, Font_Rend_Flags } EAPI RGBA_Font * -evas_common_font_memory_add(RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend) +evas_common_font_memory_add(RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend) { RGBA_Font_Int *fi; if (!fn) return NULL; - fi = evas_common_font_int_memory_load(name, size, data, data_size, wanted_rend); + fi = evas_common_font_int_memory_load(source, name, size, data, data_size, wanted_rend); if (fi) { fn->fonts = eina_list_append(fn->fonts, fi); @@ -681,11 +710,11 @@ evas_common_hinting_available(Font_Hint_Flags hinting) } EAPI RGBA_Font * -evas_common_font_memory_hinting_load(const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend) +evas_common_font_memory_hinting_load(const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend) { RGBA_Font *fn; - fn = evas_common_font_memory_load(name, size, data, data_size, wanted_rend); + fn = evas_common_font_memory_load(source, name, size, data, data_size, wanted_rend); if (fn) evas_common_font_hinting_set(fn, hinting); return fn; } @@ -709,9 +738,9 @@ evas_common_font_hinting_add(RGBA_Font *fn, const char *name, int size, Font_Hin } EAPI RGBA_Font * -evas_common_font_memory_hinting_add(RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend) +evas_common_font_memory_hinting_add(RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend) { - fn = evas_common_font_memory_add(fn, name, size, data, data_size, + fn = evas_common_font_memory_add(fn, source, name, size, data, data_size, wanted_rend); if (fn) evas_common_font_hinting_set(fn, hinting); return fn; @@ -749,6 +778,7 @@ _evas_common_font_int_clear(RGBA_Font_Int *fi) FT_Done_Glyph(fg->glyph); /* extension calls */ if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat); + if (fg->glyph_out_free) fg->glyph_out_free(fg->glyph_out); free(fg); fmap->item[i] = NULL; } diff --git a/legacy/evas/src/lib/engines/common/evas_font_main.c b/legacy/evas/src/lib/engines/common/evas_font_main.c index c09c46b83d..2240fdf57c 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_main.c +++ b/legacy/evas/src/lib/engines/common/evas_font_main.c @@ -3,6 +3,10 @@ #include "evas_font_private.h" +#ifdef EVAS_CSERVE2 +# include "../../cserve2/evas_cs2_private.h" +#endif + #include #include FT_OUTLINE_H @@ -364,7 +368,15 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt idx) { fg = _fash_gl_find(fi->fash, idx); if (fg == (void *)(-1)) return NULL; - else if (fg) return fg; + else if (fg) + { +#ifdef EVAS_CSERVE2 + if (fi->cs2_handler) + evas_cserve2_font_glyph_used(fi->cs2_handler, idx, + fi->hinting); +#endif + return fg; + } } // fg = eina_hash_find(fi->glyphs, &hindex); // if (fg) return fg; @@ -413,6 +425,7 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt idx) &outbox); fg->width = EVAS_FONT_ROUND_26_6_TO_INT(outbox.xMax - outbox.xMin); fg->x_bear = EVAS_FONT_ROUND_26_6_TO_INT(outbox.xMin); + fg->y_bear = EVAS_FONT_ROUND_26_6_TO_INT(outbox.yMax); } fg->index = idx; @@ -421,6 +434,11 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt idx) if (!fi->fash) fi->fash = _fash_gl_new(); if (fi->fash) _fash_gl_add(fi->fash, idx, fg); +#ifdef EVAS_CSERVE2 + if (fi->cs2_handler) + evas_cserve2_font_glyph_request(fi->cs2_handler, idx, fi->hinting); +#endif + // eina_hash_direct_add(fi->glyphs, &fg->index, fg); return fg; } @@ -431,6 +449,20 @@ evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *fg) int size; FT_Error error; RGBA_Font_Int *fi = fg->fi; + FT_BitmapGlyph fbg; + +#ifdef EVAS_CSERVE2 + if (fi->cs2_handler) + { + fg->glyph_out = evas_cserve2_font_glyph_bitmap_get(fi->cs2_handler, + fg->index, + fg->fi->hinting); + if (fg->glyph_out) + return EINA_TRUE; + } +#endif + + /* no cserve2 case */ FTLOCK(); error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1); if (error) @@ -444,7 +476,17 @@ evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *fg) } FTUNLOCK(); - fg->glyph_out = (FT_BitmapGlyph)fg->glyph; + fbg = (FT_BitmapGlyph)fg->glyph; + + fg->glyph_out = malloc(sizeof(RGBA_Font_Glyph_Out)); + fg->glyph_out->bitmap.rows = fbg->bitmap.rows; + fg->glyph_out->bitmap.width = fbg->bitmap.width; + fg->glyph_out->bitmap.pitch = fbg->bitmap.pitch; + fg->glyph_out->bitmap.buffer = fbg->bitmap.buffer; + fg->glyph_out->bitmap.num_grays = fbg->bitmap.num_grays; + fg->glyph_out->bitmap.pixel_mode = fbg->bitmap.pixel_mode; + + fg->glyph_out_free = free; /* This '+ 200' is just an estimation of how much memory freetype will use * on it's size. This value is not really used anywhere in code - it's * only for statistics. */ diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.c b/legacy/evas/src/lib/engines/common/evas_text_utils.c index b2e291eb41..dca75f6cd3 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.c +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.c @@ -317,6 +317,7 @@ _content_create_ot(RGBA_Font_Int *fi, const Eina_Unicode *text, LKU(fi->ft_mutex); gl_itr->x_bear = fg->x_bear; + gl_itr->y_bear = fg->y_bear; gl_itr->width = fg->width; /* text_props->info->glyph[char_index].advance = * text_props->info->glyph[char_index].index = @@ -435,6 +436,7 @@ _content_create_regular(RGBA_Font_Int *fi, const Eina_Unicode *text, gl_itr->index = idx; gl_itr->x_bear = fg->x_bear; + gl_itr->y_bear = fg->y_bear; adv = fg->glyph->advance.x >> 10; gl_itr->width = fg->width; diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.h b/legacy/evas/src/lib/engines/common/evas_text_utils.h index e30827db9b..a10ce7d569 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.h +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.h @@ -50,12 +50,10 @@ struct _Evas_Font_Glyph_Info { unsigned int index; /* Should conform to FT */ Evas_Coord x_bear; -#if 0 /* This one is rarely used, only in draw, in which we already get the glyph * so it doesn't really save time. Leaving it here just so no one will * add it thinking it was accidentally skipped */ Evas_Coord y_bear; -#endif Evas_Coord width; Evas_Coord pen_after; }; diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index 3ace2b6432..c9a9511c6b 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -400,6 +400,7 @@ typedef struct _RGBA_Font RGBA_Font; typedef struct _RGBA_Font_Int RGBA_Font_Int; typedef struct _RGBA_Font_Source RGBA_Font_Source; typedef struct _RGBA_Font_Glyph RGBA_Font_Glyph; +typedef struct _RGBA_Font_Glyph_Out RGBA_Font_Glyph_Out; typedef struct _RGBA_Gfx_Compositor RGBA_Gfx_Compositor; typedef struct _Cutout_Rect Cutout_Rect; @@ -957,6 +958,9 @@ struct _RGBA_Font_Int in order to comply with the wanted_rend. */ Eina_List *task; +#ifdef EVAS_CSERVE2 + void *cs2_handler; +#endif int generation; @@ -978,13 +982,32 @@ struct _RGBA_Font_Source } ft; }; +/* + * laziness wins for now. The parts used from the freetpye struct are + * kept intact to avoid changing the code using it until we know exactly + * what needs to be changed + */ +struct _RGBA_Font_Glyph_Out +{ + struct { + int rows; + int width; + int pitch; + unsigned char *buffer; + short num_grays; + char pixel_mode; + } bitmap; +}; + struct _RGBA_Font_Glyph { FT_UInt index; Evas_Coord width; Evas_Coord x_bear; + Evas_Coord y_bear; FT_Glyph glyph; - FT_BitmapGlyph glyph_out; + RGBA_Font_Glyph_Out *glyph_out; + void (*glyph_out_free)(void *); /* this is a problem - only 1 engine at a time can extend such a font... grrr */ void *ext_dat; void (*ext_dat_free) (void *ext_dat); diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 9d3fa90c0e..d21ab0a7ab 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -803,9 +803,9 @@ struct _Evas_Func int (*image_cache_get) (void *data); Evas_Font_Set *(*font_load) (void *data, const char *name, int size, Font_Rend_Flags wanted_rend); - Evas_Font_Set *(*font_memory_load) (void *data, char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend); + Evas_Font_Set *(*font_memory_load) (void *data, const char *source, const char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend); Evas_Font_Set *(*font_add) (void *data, Evas_Font_Set *font, const char *name, int size, Font_Rend_Flags wanted_rend); - Evas_Font_Set *(*font_memory_add) (void *data, Evas_Font_Set *font, char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend); + Evas_Font_Set *(*font_memory_add) (void *data, Evas_Font_Set *font, const char *source, const char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend); void (*font_free) (void *data, Evas_Font_Set *font); int (*font_ascent_get) (void *data, Evas_Font_Set *font); int (*font_descent_get) (void *data, Evas_Font_Set *font); diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index 0126ef003f..43e47279b9 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -1148,10 +1148,10 @@ eng_font_load(void *data __UNUSED__, const char *name, int size, } static Evas_Font_Set * -eng_font_memory_load(void *data __UNUSED__, char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend) +eng_font_memory_load(void *data __UNUSED__, const char *source, const char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend) { - return (Evas_Font_Set *) evas_common_font_memory_load(name, size, fdata, - fdata_size, wanted_rend); + return (Evas_Font_Set *) evas_common_font_memory_load(source, name, size, + fdata, fdata_size, wanted_rend); } static Evas_Font_Set * @@ -1162,10 +1162,10 @@ eng_font_add(void *data __UNUSED__, Evas_Font_Set *font, const char *name, int s } static Evas_Font_Set * -eng_font_memory_add(void *data __UNUSED__, Evas_Font_Set *font, char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend) +eng_font_memory_add(void *data __UNUSED__, Evas_Font_Set *font, const char *source, const char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend) { return (Evas_Font_Set *) evas_common_font_memory_add((RGBA_Font *) font, - name, size, fdata, fdata_size, wanted_rend); + source, name, size, fdata, fdata_size, wanted_rend); } static void