fix refcounting issue with font instances.
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 28 Jun 2012 10:13:05 +0000 (10:13 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 28 Jun 2012 10:13:05 +0000 (10:13 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@72990 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
src/lib/engines/common/evas_font.h
src/lib/engines/common/evas_font_load.c
src/lib/engines/common/evas_text_utils.c

index 3aa59d8..860ce21 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
         * Handled evas_gl_make_current to return error when either surface 
         or context is NULL.  Before, when that was the case, it just did 
         make_current(NULL, NULL) internally. 
+
+2012-04-28  Carsten Haitzler (The Rasterman)
+
+        * Fix font instance refcounting for textprops that hang around.
+
index 3769b13..313c23e 100644 (file)
@@ -42,6 +42,7 @@ EAPI RGBA_Font        *evas_common_font_load                 (const char *name,
 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 *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_int_unref            (RGBA_Font_Int *fi);
 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 *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend);
index 2307fde..4024565 100644 (file)
@@ -80,7 +80,7 @@ _evas_common_font_int_free(RGBA_Font_Int *fi)
    hb_font_destroy(fi->ft.hb_font);
 #endif
    evas_common_font_source_free(fi->src);
-   if (fi->references == 0) fonts_lru = eina_list_remove(fonts_lru, fi);
+   if (fi->references <= 0) fonts_lru = eina_list_remove(fonts_lru, fi);
    if (fi->fash) fi->fash->freeme(fi->fash);
    if (fi->inuse)
     {
@@ -509,13 +509,7 @@ evas_common_font_memory_load(const char *source, const char *name, int size, con
    fn = calloc(1, sizeof(RGBA_Font));
    if (!fn)
      {
-       fi->references--;
-       if (fi->references == 0)
-         {
-            fonts_lru = eina_list_prepend(fonts_lru, fi);
-            evas_common_font_int_modify_cache_by(fi, 1);
-            evas_common_font_flush();
-         }
+        evas_common_font_int_unref(fi);
        return NULL;
      }
    fn->fonts = eina_list_append(fn->fonts, fi);
@@ -552,13 +546,7 @@ evas_common_font_load(const char *name, int size, Font_Rend_Flags wanted_rend)
          {
             if (evas_common_font_source_load_complete(fi->src))
               {
-                 fi->references--;
-                 if (fi->references == 0)
-                   {
-                      fonts_lru = eina_list_prepend(fonts_lru, fi);
-                      evas_common_font_int_modify_cache_by(fi, 1);
-                      evas_common_font_flush();
-                   }
+                  evas_common_font_int_unref(fi);
                  return NULL;
               }
          }
@@ -567,13 +555,7 @@ evas_common_font_load(const char *name, int size, Font_Rend_Flags wanted_rend)
    fn = calloc(1, sizeof(RGBA_Font));
    if (!fn)
      {
-       fi->references--;
-       if (fi->references == 0)
-         {
-            fonts_lru = eina_list_prepend(fonts_lru, fi);
-            evas_common_font_int_modify_cache_by(fi, 1);
-            evas_common_font_flush();
-         }
+        evas_common_font_int_unref(fi);
        return NULL;
      }
 
@@ -637,6 +619,18 @@ evas_common_font_memory_add(RGBA_Font *fn, const char *source, const char *name,
 }
 
 EAPI void
+evas_common_font_int_unref(RGBA_Font_Int *fi)
+{
+   fi->references--;
+   if (fi->references == 0)
+     {
+        fonts_lru = eina_list_append(fonts_lru, fi);
+        evas_common_font_int_modify_cache_by(fi, 1);
+        evas_common_font_flush();
+     }
+}
+
+EAPI void
 evas_common_font_free(RGBA_Font *fn)
 {
    Eina_List *l;
@@ -646,14 +640,7 @@ evas_common_font_free(RGBA_Font *fn)
    fn->references--;
    if (fn->references > 0) return;
    EINA_LIST_FOREACH(fn->fonts, l, fi)
-     {
-       fi->references--;
-       if (fi->references == 0)
-         {
-            fonts_lru = eina_list_append(fonts_lru, fi);
-            evas_common_font_int_modify_cache_by(fi, 1);
-         }
-     }
+     evas_common_font_int_unref(fi);
    evas_common_font_flush();
    eina_list_free(fn->fonts);
    if (fn->fash) fn->fash->freeme(fn->fash);
@@ -758,37 +745,40 @@ _evas_common_font_int_clear(RGBA_Font_Int *fi)
         return;
      }
    evas_common_font_int_modify_cache_by(fi, -1);
-  if (fi->fash)
-    {
-      for (k = 0; k <= 0xff; k++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
-        {
-          Fash_Glyph_Map2 *fmap2 = fi->fash->bucket[k];
-          if (fmap2)
-            {
-              for (j = 0; j <= 0xff; j++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
-                {
-                  Fash_Glyph_Map *fmap = fmap2->bucket[j];
-                  if (fmap)
+   if (fi->references <= 1)
+     {
+        if (fi->fash)
+          {
+             for (k = 0; k <= 0xff; k++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
+               {
+                  Fash_Glyph_Map2 *fmap2 = fi->fash->bucket[k];
+                  if (fmap2)
                     {
-                      for (i = 0; i <= 0xff; i++)
-                        {
-                          RGBA_Font_Glyph *fg = fmap->item[i];
-                          if ((fg) && (fg != (void *)(-1)))
-                            {
-                              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;
-                            }
-                        }
+                       for (j = 0; j <= 0xff; j++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
+                         {
+                            Fash_Glyph_Map *fmap = fmap2->bucket[j];
+                            if (fmap)
+                              {
+                                 for (i = 0; i <= 0xff; i++)
+                                   {
+                                      RGBA_Font_Glyph *fg = fmap->item[i];
+                                      if ((fg) && (fg != (void *)(-1)))
+                                        {
+                                           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;
+                                        }
+                                   }
+                              }
+                         }
                     }
-                }
-            }
-        }
-      fi->fash->freeme(fi->fash);
-      fi->fash = NULL;
+               }
+             fi->fash->freeme(fi->fash);
+             fi->fash = NULL;
+          }
      }
    if (fi->inuse) fonts_use_usage -= fi->usage;
    fi->usage = 0;
index dca75f6..c1c1a23 100644 (file)
@@ -47,6 +47,8 @@ evas_common_text_props_content_ref(Evas_Text_Props *props)
       return;
 
    props->info->refcount++;
+   if (props->font_instance) 
+     ((RGBA_Font_Int *)props->font_instance)->references++;
 }
 
 void
@@ -56,6 +58,12 @@ evas_common_text_props_content_unref(Evas_Text_Props *props)
    if (!props->info)
       return;
 
+   if (props->font_instance)
+     {
+        evas_common_font_int_unref(props->font_instance);
+        props->font_instance = NULL;
+     }
+   
    if (--(props->info->refcount) == 0)
      {
         if (props->bin)
@@ -478,8 +486,14 @@ evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text,
      }
    text_props->info = calloc(1, sizeof(Evas_Text_Props_Info));
 
-   text_props->font_instance = fi;
-
+   if (text_props->font_instance != fi)
+     {
+        if (text_props->font_instance)
+          evas_common_font_int_unref(text_props->font_instance);
+        text_props->font_instance = fi;
+        fi->references++;
+     }
+   
    evas_common_font_int_reload(fi);
    if (fi->src->current_size != fi->size)
      {