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);
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);
#include "evas_cs2.h"
#include "evas_cs2_private.h"
+#include "evas_cs2_utils.h"
#ifdef EVAS_CSERVE2
}
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;
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:
{
_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
};
typedef struct _Data_Entry Data_Entry;
+typedef struct _Font_Entry Font_Entry;
int evas_cserve2_init(void);
int evas_cserve2_shutdown(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
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);
#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)
#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
{
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 */
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
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;
EVAS_FONT_WALK_TEXT_START()
{
Evas_Glyph glyph;
- RGBA_Font_Glyph *fg;
FT_UInt idx;
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
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;
}
#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>
fonts_use_usage -= fi->usage;
fi->usage = 0;
}
+#ifdef EVAS_CSERVE2
+ evas_cserve2_font_free(fi->cs2_handler);
+#endif
free(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;
}
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;
}
}
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));
}
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);
}
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;
}
}
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;
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;
}
#include "evas_font_private.h"
+#ifdef EVAS_CSERVE2
+# include "../../cserve2/evas_cs2_private.h"
+#endif
+
#include <assert.h>
#include FT_OUTLINE_H
{
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;
&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;
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;
}
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)
}
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. */
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 =
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;
{
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;
};
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;
in order to comply with the wanted_rend. */
Eina_List *task;
+#ifdef EVAS_CSERVE2
+ void *cs2_handler;
+#endif
int generation;
} 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);
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);
}
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 *
}
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