evas_text_grid: remove optimisation (will come back later) to make code more readable
authorBoris Faure <billiob@gmail.com>
Wed, 2 Sep 2015 18:50:31 +0000 (20:50 +0200)
committerBoris Faure <billiob@gmail.com>
Sat, 12 Mar 2016 17:10:03 +0000 (18:10 +0100)
src/lib/evas/canvas/evas_object_textgrid.c

index 8742a4c..45aeab6 100644 (file)
@@ -21,18 +21,6 @@ typedef struct _Evas_Object_Textgrid_Row   Evas_Object_Textgrid_Row;
 typedef struct _Evas_Object_Textgrid_Rect  Evas_Object_Textgrid_Rect;
 typedef struct _Evas_Object_Textgrid_Text  Evas_Object_Textgrid_Text;
 typedef struct _Evas_Object_Textgrid_Line  Evas_Object_Textgrid_Line;
-typedef struct _Evas_Textgrid_Hash_Master  Evas_Textgrid_Hash_Master;
-typedef struct _Evas_Textgrid_Hash_Glyphs  Evas_Textgrid_Hash_Glyphs;
-
-struct _Evas_Textgrid_Hash_Master
-{
-   int next[16];
-};
-
-struct _Evas_Textgrid_Hash_Glyphs
-{
-   Evas_Text_Props props[256];
-};
 
 struct _Evas_Textgrid_Data
 {
@@ -58,18 +46,6 @@ struct _Evas_Textgrid_Data
 
    Evas_Font_Set                 *font;
 
-   Evas_Textgrid_Hash_Master     *master;
-   Evas_Textgrid_Hash_Glyphs     *glyphs;
-   unsigned char                 *master_used;
-   unsigned char                 *glyphs_used;
-   unsigned int                   master_length;
-   unsigned int                   glyphs_length;
-
-   unsigned int                   last_mask;
-   Evas_Textgrid_Hash_Glyphs     *last_glyphs;
-
-   Eina_Array                     glyphs_cleanup;
-
    unsigned int                   changed : 1;
    unsigned int                   core_change : 1;
    unsigned int                   row_change : 1;
@@ -101,7 +77,7 @@ struct _Evas_Object_Textgrid_Text
 {
    unsigned char r, g, b, a;
    int x;
-   unsigned int text_props_index;
+   Evas_Text_Props text_props;
 };
 
 struct _Evas_Object_Textgrid_Line
@@ -166,197 +142,6 @@ static const Evas_Object_Func object_func =
    NULL
 };
 
-/* almost generic private array data type */
-static int
-evas_object_textgrid_textprop_get(Evas_Object *eo_obj, Evas_Textgrid_Data *o, Eina_Unicode codepoint,
-                                  unsigned int glyphs_index, unsigned char *used)
-{
-   Evas_Textgrid_Hash_Glyphs *glyph;
-   unsigned char idx = codepoint & 0xFF;
-
-   glyph = &(o->glyphs[glyphs_index]);
-
-   if (!glyph->props[idx].info)
-     {
-        Evas_Font_Instance *script_fi = NULL;
-        Evas_Font_Instance *cur_fi = NULL;
-        Evas_Script_Type script;
-
-        script = evas_common_language_script_type_get(&codepoint, 1);
-        Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
-        ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi, script, &codepoint, 1);
-        memset(&(glyph->props[idx]), 0, sizeof(Evas_Text_Props));
-        evas_common_text_props_script_set(&(glyph->props[idx]), script);
-        ENFN->font_text_props_info_create(ENDT, script_fi, &codepoint,
-                                          &(glyph->props[idx]), NULL, 0, 1,
-                                          EVAS_TEXT_PROPS_MODE_NONE,
-                                          o->cur.font_description->lang);
-        (*used)++;
-     }
-   else
-     {
-        evas_common_text_props_content_ref(&(glyph->props[idx]));
-     }
-   
-   return glyphs_index << 8 | (unsigned int) idx;
-}
-
-static int
-evas_object_textgrid_textprop_ref(Evas_Object *eo_obj, Evas_Textgrid_Data *o, Eina_Unicode codepoint)
-{
-   unsigned int mask = 0xF0000000;
-   unsigned int shift = 28;
-   unsigned int offset = 0;
-   unsigned int glyphs_index;
-
-   if (o->last_glyphs)
-     {
-        if ((o->last_mask) && ((o->last_mask & codepoint) == o->last_mask))
-          goto end;
-     }
-
-   if (!o->master)
-     {
-        o->master = calloc(6, sizeof (Evas_Textgrid_Hash_Master));
-        o->master_used = calloc(6, sizeof (unsigned char));
-        o->glyphs = calloc(1, sizeof (Evas_Textgrid_Hash_Glyphs));
-        o->glyphs_used = calloc(1, sizeof (unsigned char));
-        if (!o->master || !o->master_used || !o->glyphs || !o->glyphs_used)
-          {
-             free(o->master);
-             o->master = NULL;
-             free(o->master_used);
-             o->master_used = NULL;
-             free(o->glyphs);
-             o->glyphs = NULL;
-             free(o->glyphs_used);
-             o->glyphs_used = NULL;
-             return 0xFFFFFFFF;
-          }
-
-        while (shift > 8)
-          {
-             o->master[offset].next[(mask & codepoint) >> shift] = offset + 1;
-             o->master_used[offset] = 1;
-             offset++;
-             shift -= 4;
-             mask >>= 4;
-          }
-
-        o->glyphs_length = 1;
-        o->master_length = 6;
-        o->master[5].next[(codepoint & 0xF00) >> 8] = 0xFF000000;
-        o->last_glyphs = o->glyphs;
-        o->last_mask = codepoint & 0xFFFFFF00;
-
-        goto end;
-     }
-
-   while ((shift > 8)
-          && (o->master[offset].next[(codepoint & mask) >> shift] != 0))
-     {
-        offset = o->master[offset].next[(codepoint & mask) >> shift];
-        mask >>= 4;
-        shift -= 4;
-     }
-
-   if (shift > 8)
-     {
-        Evas_Textgrid_Hash_Master *tmp;
-        unsigned char *tmp_used;
-        int master_count;
-        int count;
-        int end;
-
-        count = (shift - 8) / 4;
-        master_count = o->master_length + count;
-
-        /* FIXME: find empty entry */
-        tmp = realloc(o->master, master_count * sizeof (Evas_Textgrid_Hash_Master));
-        if (!tmp) return 0xFFFFFFFF;
-        o->master = tmp;
-        tmp_used = realloc(o->master_used, master_count);
-        if (!tmp_used) return 0xFFFFFFFF;
-        o->master_used = tmp_used;
-
-        memset(o->master + o->master_length, 0, count * sizeof (Evas_Textgrid_Hash_Master));
-        memset(o->master_used + o->master_length, 1, count);
-        end = o->master_length;
-        o->master_length = master_count;
-
-        while (shift > 8)
-          {
-             o->master[offset].next[(mask & codepoint) >> shift] = end;
-             o->master_used[offset] = 1;
-             end++;
-             offset = end;
-             shift -= 4;
-             mask >>= 4;
-          }
-        offset--;
-     }
-   if ((o->master[offset].next[(codepoint & mask) >> shift] == 0)
-       || ((o->master[offset].next[(codepoint & mask) >> shift] & 0xFFFFFF) >= o->glyphs_length))
-     {
-        Evas_Textgrid_Hash_Glyphs *tmp;
-        unsigned char *tmp_used;
-        int count;
-
-        /* FIXME: find empty entry */
-        if (o->master[offset].next[(codepoint & mask) >> shift] == 0)
-          count = o->glyphs_length + 1;
-        else
-          count = (o->master[offset].next[(codepoint & mask) >> shift] & 0xFFFFFF) + 1;
-        tmp = realloc(o->glyphs, count * sizeof (Evas_Textgrid_Hash_Glyphs));
-        if (!tmp) return 0xFFFFFFFF;
-        o->glyphs = tmp;
-        tmp_used = realloc(o->glyphs_used, count * sizeof (unsigned char));
-        if (!tmp_used) return 0xFFFFFFFF;
-        o->glyphs_used = tmp_used;
-
-        // FIXME: What should we write when allocating more than one new entry?
-        o->master[offset].next[(codepoint & mask) >> shift] = o->glyphs_length + 0xFF000000;
-
-        memset(o->glyphs + o->glyphs_length, 0, (count - o->glyphs_length) * sizeof (Evas_Textgrid_Hash_Glyphs));
-        memset(o->glyphs_used, 0, (count - o->glyphs_length) * sizeof(o->glyphs_used[0]));
-        o->glyphs_length = count;
-     }
-
-   o->last_glyphs = o->glyphs + (o->master[offset].next[(codepoint & mask) >> shift] & 0xFFFFFF);
-   o->last_mask = codepoint & 0xFFFFFF00;
-
- end:
-   glyphs_index = o->last_glyphs - o->glyphs;
-   return evas_object_textgrid_textprop_get(eo_obj, o, codepoint, glyphs_index,
-                                            &(o->glyphs_used[glyphs_index]));
-}
-
-static Evas_Text_Props *
-_textprop_from_idx(Evas_Textgrid_Data *o, unsigned int props_index)
-{
-   return &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
-}
-
-
-static void
-evas_object_textgrid_textprop_unref(Evas_Textgrid_Data *o, unsigned int props_index)
-{
-   Evas_Text_Props *props;
-
-   props = _textprop_from_idx(o, props_index);
-
-   if (props->info)
-     {
-        if (props->info->refcount == 1)
-          eina_array_push(&o->glyphs_cleanup,
-                          (void *)((uintptr_t)props_index));
-        else
-          {
-             evas_common_text_props_content_nofree_unref(props);
-          }
-     }
-}
-
 /* all nice and private */
 static void
 evas_object_textgrid_init(Evas_Object *eo_obj)
@@ -372,11 +157,11 @@ evas_object_textgrid_init(Evas_Object *eo_obj)
    o->prev = o->cur;
    eina_array_step_set(&o->cur.palette_standard, sizeof (Eina_Array), 16);
    eina_array_step_set(&o->cur.palette_extended, sizeof (Eina_Array), 16);
-   eina_array_step_set(&o->glyphs_cleanup, sizeof (Eina_Array), 16);
 }
 
 static void
-evas_object_textgrid_row_clear(Evas_Textgrid_Data *o, Evas_Object_Textgrid_Row *r)
+evas_object_textgrid_row_clear(Evas_Textgrid_Data *o EINA_UNUSED,
+                               Evas_Object_Textgrid_Row *r)
 {
    int i;
 
@@ -390,11 +175,7 @@ evas_object_textgrid_row_clear(Evas_Textgrid_Data *o, Evas_Object_Textgrid_Row *
    if (r->texts)
      {
         for (i = 0; i < r->texts_num; i++)
-          if (r->texts[i].text_props_index != 0xFFFFFFFF)
-            {
-               evas_object_textgrid_textprop_unref(o, r->texts[i].text_props_index);
-               r->texts[i].text_props_index = 0xFFFFFFFF;
-            }
+          evas_common_text_props_content_unref(&(r->texts[i].text_props));
         free(r->texts);
         r->texts = NULL;
         r->texts_num = 0;
@@ -445,32 +226,6 @@ evas_object_textgrid_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
      free(c);
    eina_array_flush(&o->cur.palette_extended);
 
-   while (eina_array_count(&o->glyphs_cleanup) > 0)
-     {
-        Evas_Text_Props *prop;
-        unsigned int props_index;
-
-        props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
-        prop = &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
-
-        evas_common_text_props_content_nofree_unref(prop);
-        if (!prop->info)
-          {
-             o->glyphs_used[props_index >> 8]--;
-
-             if (!o->glyphs_used[props_index >> 8])
-               {
-                  /* FIXME: cleanup the master tree */
-               }
-          }
-     }
-   eina_array_flush(&o->glyphs_cleanup);
-
-   free(o->master);
-   free(o->glyphs);
-   free(o->master_used);
-   free(o->glyphs_used);
-
    o->magic = 0;
 }
 
@@ -484,7 +239,9 @@ _evas_textgrid_eo_base_destructor(Eo *eo_obj, Evas_Textgrid_Data *o EINA_UNUSED)
 }
 
 static void
-evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row, int x, int w, int r, int g, int b, int a)
+evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row,
+                                     int x, int w,
+                                     int r, int g, int b, int a)
 {
    row->rects_num++;
    if (row->rects_num > row->rects_alloc)
@@ -509,9 +266,16 @@ evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row, int x, int w
 }
 
 static void
-evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object *eo_obj, Evas_Textgrid_Data *o, int x, Eina_Unicode codepoint, int r, int g, int b, int a)
+evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row,
+                                     Evas_Object_Protected_Data *obj,
+                                     Evas_Textgrid_Data *o,
+                                     int x,
+                                     Eina_Unicode codepoint,
+                                     int r, int g, int b, int a)
 {
-   unsigned int text_props_index;
+   Evas_Script_Type script;
+   Evas_Font_Instance *script_fi = NULL;
+   Evas_Font_Instance *cur_fi = NULL;
 
    row->texts_num++;
    if (row->texts_num > row->texts_alloc)
@@ -528,9 +292,19 @@ evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object
         row->texts = t;
      }
 
-   text_props_index = evas_object_textgrid_textprop_ref(eo_obj, o, codepoint);
+   script = evas_common_language_script_type_get(&codepoint, 1);
+   ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi,
+                          script, &codepoint, 1);
+   memset(&(row->texts[row->texts_num - 1].text_props), 0,
+          sizeof(Evas_Text_Props));
+   evas_common_text_props_script_set
+     (&(row->texts[row->texts_num - 1].text_props), script);
+   ENFN->font_text_props_info_create
+     (ENDT, script_fi, &codepoint,
+         &(row->texts[row->texts_num - 1].text_props), NULL, 0, 1,
+         EVAS_TEXT_PROPS_MODE_NONE,
+         o->cur.font_description->lang);
 
-   row->texts[row->texts_num - 1].text_props_index = text_props_index;
    row->texts[row->texts_num - 1].x = x;
    row->texts[row->texts_num - 1].r = r;
    row->texts[row->texts_num - 1].g = g;
@@ -577,7 +351,7 @@ _drop_glyphs_ref(const void *container EINA_UNUSED, void *data, void *fdata)
 }
 
 static void
-evas_object_textgrid_render(Evas_Object *eo_obj,
+evas_object_textgrid_render(Evas_Object *eo_obj EINA_UNUSED,
                            Evas_Object_Protected_Data *obj,
                            void *type_private_data,
                            void *output, void *context, void *surface, int x, int y, Eina_Bool do_async)
@@ -662,7 +436,8 @@ evas_object_textgrid_render(Evas_Object *eo_obj,
                   if ((c) && (c->a > 0))
                     {
                        if (cells->codepoint > 0)
-                         evas_object_textgrid_row_text_append(row, eo_obj, o, xp,
+                         evas_object_textgrid_row_text_append(row, obj,
+                                                              o, xp,
                                                               cells->codepoint,
                                                               c->r, c->g, c->b, c->a);
                        // XXX: underlines and strikethroughs dont get
@@ -729,7 +504,7 @@ evas_object_textgrid_render(Evas_Object *eo_obj,
                     {
                        Evas_Text_Props *props;
 
-                       props = _textprop_from_idx(o, row->texts[xx].text_props_index);
+                       props = &row->texts[xx].text_props;
 
                        evas_common_font_draw_prepare(props);
 
@@ -770,7 +545,7 @@ evas_object_textgrid_render(Evas_Object *eo_obj,
                        int              tx = xp + row->texts[xx].x;
                        int              ty = yp + o->ascent;
 
-                       props = _textprop_from_idx(o, row->texts[xx].text_props_index);
+                       props = &row->texts[xx].text_props;
 
                        r = row->texts[xx].r;
                        g = row->texts[xx].g;
@@ -960,26 +735,6 @@ evas_object_textgrid_render_post(Evas_Object *eo_obj,
    /* move cur to prev safely for object data */
    evas_object_cur_prev(eo_obj);
    o->prev = o->cur;
-
-   while (eina_array_count(&o->glyphs_cleanup) > 0)
-     {
-        Evas_Text_Props *prop;
-        unsigned int props_index;
-
-        props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
-        prop = _textprop_from_idx(o, props_index);
-
-        evas_common_text_props_content_nofree_unref(prop);
-        if (!prop->info)
-          {
-             o->glyphs_used[props_index >> 8]--;
-
-             if (!o->glyphs_used[props_index >> 8])
-               {
-                  /* FIXME: cleanup the master tree */
-               }
-          }
-     }
 }
 
 static unsigned int
@@ -1263,27 +1018,6 @@ _evas_textgrid_efl_text_properties_font_set(Eo *eo_obj, Evas_Textgrid_Data *o, c
    o->core_change = 1;
    evas_object_textgrid_rows_clear(eo_obj);
    evas_object_change(eo_obj, obj);
-
-   /* Force destroy of all cached Evas_Text_Props */
-   while (eina_array_count(&o->glyphs_cleanup) > 0)
-     {
-        Evas_Text_Props *prop;
-        unsigned int props_index;
-
-        props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
-        prop = _textprop_from_idx(o, props_index);
-
-        evas_common_text_props_content_nofree_unref(prop);
-        if (!prop->info)
-          {
-             o->glyphs_used[props_index >> 8]--;
-
-             if (!o->glyphs_used[props_index >> 8])
-               {
-                  /* FIXME: cleanup the master tree */
-               }
-          }
-     }
 }
 
 EOLIAN static void