evas/cserve2: Fix font hinting
authorJean-Philippe Andre <jp.andre@samsung.com>
Mon, 2 Sep 2013 07:17:05 +0000 (16:17 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 28 Oct 2013 06:47:15 +0000 (15:47 +0900)
cserve2 was not handling font hints properly in the server side
Add some consistency checks and separate glyphs per hinting value

src/bin/evas/evas_cserve2_cache.c
src/bin/evas/evas_cserve2_debug.c
src/bin/evas/evas_cserve2_shm_debug.c
src/lib/evas/cserve2/evas_cs2.h
src/lib/evas/cserve2/evas_cs2_client.c

index b71ce01..40cd55d 100644 (file)
@@ -73,7 +73,7 @@ struct _Font_Entry {
    unsigned int font_data_id;
    Font_Source *src;
    void *ft; // Font_Info
-   Fash_Glyph2 *glyph_entries; // Fast access to the Glyph_Entry objects
+   Fash_Glyph2 *glyph_entries[3]; // Fast access to the Glyph_Entry objects
    Shared_Array *glyph_datas; // Contains the Glyph_Data objects
    unsigned int nglyphs;
    Eina_Bool unused : 1;
@@ -1130,7 +1130,7 @@ static void
 _font_entry_free(Font_Entry *fe)
 {
    Font_Data *fd;
-   int size;
+   int size, k;
 
    if (!fe) return;
    size = _font_entry_memory_usage_get(fe);
@@ -1148,7 +1148,8 @@ _font_entry_free(Font_Entry *fe)
         cserve2_shared_string_del(fd->name);
      }
 
-   fash_gl_free(fe->glyph_entries);
+   for (k = 0; k < 3; k++)
+     fash_gl_free(fe->glyph_entries[k]);
    cserve2_shared_array_del(fe->glyph_datas);
    cserve2_shared_mempool_del(fe->mempool);
    cserve2_font_ft_free(fe->ft);
@@ -1720,16 +1721,23 @@ static Slave_Request_Funcs _font_load_funcs = {
 static Eina_Bool
 _glyphs_request_check(Glyphs_Request *req, Eina_Bool report_load)
 {
-   unsigned int i;
+   unsigned int i, hint;
    Font_Entry *fe = req->fe;
 
    req->answer = malloc(sizeof(*req->answer) * req->nglyphs);
    req->nanswer = 0;
 
+   hint = req->hint;
+   if (hint > 2)
+     {
+        WRN("Invalid font hint requested. Defaulting to 0.");
+        hint = 0;
+     }
+
    for (i = req->current; i < req->nglyphs; i++)
      {
         Glyph_Entry *ge;
-        ge = fash_gl_find(fe->glyph_entries, req->glyphs[i]);
+        ge = fash_gl_find(fe->glyph_entries[hint], req->glyphs[i]);
         if (ge)
           {
              req->answer[req->nanswer++] = ge;
@@ -1767,7 +1775,7 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
    size = sizeof(Msg_Font_Glyphs_Loaded);
    size += sizeof(int) * 2;
    size += shmname_size;
-   size += req->nanswer * 9 * sizeof(int);
+   size += req->nanswer * 10 * sizeof(int);
 
    response = malloc(size);
    if (!response) return NULL;
@@ -1813,6 +1821,8 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
         buf += sizeof(int);
         memcpy(buf, &gldata->pixel_mode, sizeof(int));
         buf += sizeof(int);
+        memcpy(buf, &gldata->hint, sizeof(int));
+        buf += sizeof(int);
      }
 
    *resp_size = size;
@@ -1915,7 +1925,7 @@ _glyphs_request_free(Glyphs_Request *req)
 static void
 _glyphs_load_request_prepare(Glyphs_Request *req)
 {
-   unsigned int i, max;
+   unsigned int i, max, hint;
    req->nrender = 0;
    Font_Entry *fe = req->fe;
 
@@ -1925,6 +1935,13 @@ _glyphs_load_request_prepare(Glyphs_Request *req)
         return;
      }
 
+   hint = req->hint;
+   if (hint > 2)
+     {
+        WRN("Invalid font hint requested. Defaulting to 0.");
+        hint = 0;
+     }
+
    // Won't render more than this number of glyphs
    max = req->nglyphs - req->nanswer;
    req->render = malloc(sizeof(*req->render) * max);
@@ -1932,7 +1949,7 @@ _glyphs_load_request_prepare(Glyphs_Request *req)
    for (i = req->current; i < req->nglyphs; i++)
      {
         Glyph_Entry *ge;
-        ge = fash_gl_find(fe->glyph_entries, req->glyphs[i]);
+        ge = fash_gl_find(fe->glyph_entries[hint], req->glyphs[i]);
         if (ge)
           {
              req->answer[req->nanswer++] = ge;
@@ -1987,13 +2004,20 @@ _glyphs_load_request_response(Glyphs_Request *req,
 {
    Font_Entry *fe = req->fe;
    Shared_Mempool *mempool = msg->mempool;
-   unsigned int j;
+   unsigned int j, hint;
    string_t shm_id = 0;
    Font_Data *fd;
 
    if (!msg->nglyphs)
      return _glyphs_loaded_msg_create(req, size);
 
+   hint = req->hint;
+   if (hint > 2)
+     {
+        WRN("Invalid font hint requested. Defaulting to 0.");
+        hint = 0;
+     }
+
    fd = _font_data_find(fe->font_data_id);
 
    DBG("Font memory usage [begin]: %d / %d", font_mem_usage, max_font_usage);
@@ -2022,7 +2046,7 @@ _glyphs_load_request_response(Glyphs_Request *req,
      {
         Glyph_Entry *gl;
 
-        gl = fash_gl_find(fe->glyph_entries, msg->glyphs[j].index);
+        gl = fash_gl_find(fe->glyph_entries[hint], msg->glyphs[j].index);
         if (!gl)
           {
              int glyph_id, orig_mapsize, new_mapsize;
@@ -2056,9 +2080,10 @@ _glyphs_load_request_response(Glyphs_Request *req,
              gldata->pitch = msg->glyphs[j].pitch;
              gldata->num_grays = msg->glyphs[j].num_grays;
              gldata->pixel_mode = msg->glyphs[j].pixel_mode;
+             gldata->hint = hint;
 
              fe->nglyphs++;
-             fash_gl_add(fe->glyph_entries, gldata->index, gl);
+             fash_gl_add(fe->glyph_entries[hint], gldata->index, gl);
 
              new_mapsize = cserve2_shared_array_map_size_get(fe->glyph_datas);
              font_mem_usage += new_mapsize - orig_mapsize;
@@ -2845,6 +2870,7 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name,
    Font_Entry *fe;
    char *fullname;
    int fd_index;
+   int k;
 
    if (source && !*source)
      source = NULL;
@@ -2879,7 +2905,8 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name,
    fe->size = size;
    fe->dpi = dpi;
    fe->base.type = CSERVE2_FONT_ENTRY;
-   fe->glyph_entries = fash_gl_new(_glyph_free_cb);
+   for (k = 0; k < 3; k++)
+     fe->glyph_entries[k] = fash_gl_new(_glyph_free_cb);
    ref = _entry_reference_add((Entry *)fe, client, 0);
    client->fonts.referencing = eina_list_append(client->fonts.referencing, ref);
    fe->unused = EINA_FALSE;
index 7eaea5d..92c8c88 100644 (file)
@@ -300,10 +300,10 @@ _glyph_data_print(Glyph_Data *gd)
         "FT_PIXEL_MODE_LCD_V"
    };
    printf("  GLYPH id: %-4u refcount %-2u: index: %-6u offset: %-6u size: %-3u "
-          "%2ux%-3u pitch: %-2u grays: %-3u pixel mode: %s\n",
+          "%2ux%-3u pitch: %-2u grays: %-3u pixel mode: %s hint: %d\n",
           gd->id, gd->refcount, gd->index, gd->offset, gd->size,
           gd->width, gd->rows, gd->pitch,
-          gd->num_grays, pxmode[gd->pixel_mode]);
+          gd->num_grays, pxmode[gd->pixel_mode], gd->hint);
 }
 
 static void
index bde62bd..426fd67 100644 (file)
@@ -586,7 +586,7 @@ _glyphs_all_print(Shm_File *sf)
    int nglyphs = 0;
    int mem_used = 0;
 
-   printf("  GlyphID Refcnt  Index  Size  Rows Width Pitch Grays  Mode  "
+   printf("  GlyphID Refcnt  Index  Size  Rows Width Pitch Grays H M  "
           "BufID Offset ShmPath\n");
 
    for (k = 0; k < sf->header->count; k++)
@@ -597,9 +597,9 @@ _glyphs_all_print(Shm_File *sf)
         if (!gd) break;
         if (!gd->id) continue;
 
-        printf(" %8u %6u %6u %5u %5u %5u %5u %5u %5u %6u %6u '%s'\n",
+        printf(" %8u %6u %6u %5u %5u %5u %5u %5u %1u %1u %6u %6u '%s'\n",
                gd->id, gd->refcount, gd->index, gd->size, gd->rows, gd->width,
-               gd->pitch, gd->num_grays, gd->pixel_mode, gd->buffer_id,
+               gd->pitch, gd->num_grays, gd->hint, gd->pixel_mode, gd->buffer_id,
                gd->offset, _shared_string_get(gd->shm_id));
 
         nglyphs++;
@@ -621,7 +621,8 @@ _fonts_all_print_full(void)
 
    printf("List of loaded fonts: %s\n", eina_file_filename_get(sf_fonts->f));
    printf("Rendering flags: "
-          "R: Regular, S: Slanted, W: Weight, X: Invalid\n\n");
+          "R: Regular, S: Slanted, W: Weight, X: Invalid\n");
+   printf("H: Hint, M: Pixel mode\n\n");
    printf_newline(0);
 
    for (k = 0; k < sf_fonts->header->count; k++)
index bcba89a..a47c384 100644 (file)
@@ -373,6 +373,7 @@ struct _Glyph_Data {
    uint32_t pitch;
    uint32_t num_grays;
    uint32_t pixel_mode;
+   uint32_t hint;
 };
 
 struct _Msg_Error {
index 1538b49..e32dc1d 100644 (file)
@@ -1434,6 +1434,7 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints)
              gd = &(fe->map->index.entries.gldata[k]);
              if (!gd->id) break;
              if (!gd->refcount) continue;
+             if (gd->hint != hints) continue;
 
              tot++;
              gl = fash_gl_find(fe->fash[hints], gd->index);
@@ -1523,7 +1524,7 @@ _glyph_request_cb(void *data, const void *msg, int size)
    for (i = 0; i < nglyphs; i++)
      {
         string_t shm_id;
-        unsigned int idx, offset, glsize;
+        unsigned int idx, offset, glsize, hints;
         int rows, width, pitch, num_grays, pixel_mode;
         CS_Glyph_Out *gl;
 
@@ -1549,8 +1550,15 @@ _glyph_request_cb(void *data, const void *msg, int size)
         buf += sizeof(int);
         memcpy(&pixel_mode, buf, sizeof(int));
         buf += sizeof(int);
+        memcpy(&hints, buf, sizeof(int));
+        buf += sizeof(int);
+        if (hints != grd->hints)
+          {
+             WRN("Invalid hints received: %d vs %d. Skip.", hints, grd->hints);
+             continue;
+          }
 
-        gl = fash_gl_find(fe->fash[grd->hints], idx);
+        gl = fash_gl_find(fe->fash[hints], idx);
         if (gl)
           {
              gl->map = fe->map;