evas/cserve2: CServe2 client side lib modifications.

Add the calls to request font loading and glyphs on the client lib.



SVN revision: 72700
This commit is contained in:
Rafael Antognolli 2012-06-22 20:31:31 +00:00
parent 64fecc2fab
commit 2f3426b67c
13 changed files with 675 additions and 74 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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 <hb.h>
# include <hb-ft.h>
@ -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;
}

View File

@ -3,6 +3,10 @@
#include "evas_font_private.h"
#ifdef EVAS_CSERVE2
# include "../../cserve2/evas_cs2_private.h"
#endif
#include <assert.h>
#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. */

View File

@ -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;

View File

@ -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;
};

View File

@ -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);

View File

@ -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);

View File

@ -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