evas/cserve2: CServe2 client side lib modifications.
authorantognolli <antognolli@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 22 Jun 2012 20:31:31 +0000 (20:31 +0000)
committerantognolli <antognolli@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 22 Jun 2012 20:31:31 +0000 (20:31 +0000)
Add the calls to request font loading and glyphs on the client lib.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@72700 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

13 files changed:
src/lib/canvas/evas_font_dir.c
src/lib/cserve2/evas_cs2_client.c
src/lib/cserve2/evas_cs2_private.h
src/lib/engines/common/evas_font.h
src/lib/engines/common/evas_font_default_walk.x
src/lib/engines/common/evas_font_draw.c
src/lib/engines/common/evas_font_load.c
src/lib/engines/common/evas_font_main.c
src/lib/engines/common/evas_text_utils.c
src/lib/engines/common/evas_text_utils.h
src/lib/include/evas_common.h
src/lib/include/evas_private.h
src/modules/engines/software_generic/evas_engine.c

index e97f7f7..aa0d9c3 100644 (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);
index 1b93ccd..ddf0186 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "evas_cs2.h"
 #include "evas_cs2_private.h"
+#include "evas_cs2_utils.h"
 
 #ifdef EVAS_CSERVE2
 
@@ -130,15 +131,37 @@ _request_answer_add(Message_Type type, unsigned int rid, Op_Callback cb, void *d
 }
 
 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
index c0dde77..4373bfd 100644 (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
index ed6655b..3769b13 100644 (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);
index f6e4520..7636201 100644 (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)
index 614e56e..5a5bb7e 100644 (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;
 }
 
index 8e0bc15..2307fde 100644 (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;
                             }
index c09c46b..2240fdf 100644 (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. */
index b2e291e..dca75f6 100644 (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;
 
index e30827d..a10ce7d 100644 (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;
 };
index 3ace2b6..c9a9511 100644 (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);
index 9d3fa90..d21ab0a 100644 (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);
index 0126ef0..43e4727 100644 (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