diff --git a/ChangeLog b/ChangeLog index 1b0dfbec57..80b8096e66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-11-21 Carsten Haitzler (The Rasterman) + + * Fixed leak in textblock and text props in general that made + textblock recalcs lead very badly. Required changed to textgrid + though a sit relied on the leaky behavior. + 2012-11-16 Sung W. Park (sung_) * Fixed glGetIntegerv() in Direct Rendering mode for Evas GL diff --git a/NEWS b/NEWS index 46080388ab..f35cd73752 100644 --- a/NEWS +++ b/NEWS @@ -26,3 +26,4 @@ Fixes: This frixes a break in compositing on new intel mesa drivers. * Fixed glGetIntegerv() in Direct Rendering mode for Evas GL to properly handle GL_SCISSOR_BOX and GL_VIEWPORT parameters. + * Fixed textblock textprop leak. diff --git a/src/lib/evas/canvas/evas_object_textgrid.c b/src/lib/evas/canvas/evas_object_textgrid.c index c5a651b503..3ff5c6d214 100644 --- a/src/lib/evas/canvas/evas_object_textgrid.c +++ b/src/lib/evas/canvas/evas_object_textgrid.c @@ -197,7 +197,7 @@ evas_object_textgrid_textprop_ref(Evas_Object *eo_obj, Evas_Object_Textgrid *o, if (o->last_glyphs) { - if (o->last_mask && (o->last_mask & codepoint) == o->last_mask) + if ((o->last_mask) && ((o->last_mask & codepoint) == o->last_mask)) goto end; } @@ -238,8 +238,8 @@ evas_object_textgrid_textprop_ref(Evas_Object *eo_obj, Evas_Object_Textgrid *o, goto end; } - while (shift > 8 - && o->master[offset].next[(codepoint & mask) >> shift] != 0) + while ((shift > 8) + && (o->master[offset].next[(codepoint & mask) >> shift] != 0)) { offset = o->master[offset].next[(codepoint & mask) >> shift]; mask >>= 4; @@ -325,7 +325,12 @@ evas_object_textgrid_textprop_unref(Evas_Object_Textgrid *o, unsigned int props_ eina_array_push(&o->glyphs_cleanup, (void *)((uintptr_t)props_index)); else - evas_common_text_props_content_unref(props); + { + Evas_Glyph *glyphs = props->glyphs; + int glyphs_length = props->glyphs_length; + + evas_common_text_props_content_nofree_unref(props); + } } } @@ -441,8 +446,8 @@ evas_object_textgrid_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) 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_unref(prop); + + evas_common_text_props_content_nofree_unref(prop); if (!prop->info) { o->glyphs_used[props_index >> 8]--; @@ -840,7 +845,7 @@ evas_object_textgrid_render_post(Evas_Object *eo_obj, Evas_Object_Protected_Data 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_unref(prop); + evas_common_text_props_content_nofree_unref(prop); if (!prop->info) { o->glyphs_used[props_index >> 8]--; @@ -1197,7 +1202,7 @@ _font_set(Eo *eo_obj, void *_pd, va_list *list) 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_unref(prop); + evas_common_text_props_content_nofree_unref(prop); if (!prop->info) { o->glyphs_used[props_index >> 8]--; diff --git a/src/lib/evas/common/evas_text_utils.c b/src/lib/evas/common/evas_text_utils.c index acdcc0042f..7abf07fa6f 100644 --- a/src/lib/evas/common/evas_text_utils.c +++ b/src/lib/evas/common/evas_text_utils.c @@ -53,6 +53,36 @@ evas_common_text_props_content_ref(Evas_Text_Props *props) ((RGBA_Font_Int *)props->font_instance)->references++; } +void +evas_common_text_props_content_nofree_unref(Evas_Text_Props *props) +{ + /* No content in this case */ + 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) + { + free(props->glyphs); + props->glyphs = NULL; + props->glyphs_length = 0; + + if (props->info->glyph) + free(props->info->glyph); +#ifdef OT_SUPPORT + if (props->info->ot) + free(props->info->ot); +#endif + free(props->info); + props->info = NULL; + } +} + void evas_common_text_props_content_unref(Evas_Text_Props *props) { @@ -66,12 +96,12 @@ evas_common_text_props_content_unref(Evas_Text_Props *props) props->font_instance = NULL; } + free(props->glyphs); + props->glyphs = NULL; + props->glyphs_length = 0; + if (--(props->info->refcount) == 0) { - free(props->glyphs); - props->glyphs = NULL; - props->glyphs_length = 0; - if (props->info->glyph) free(props->info->glyph); #ifdef OT_SUPPORT diff --git a/src/lib/evas/common/evas_text_utils.h b/src/lib/evas/common/evas_text_utils.h index 675df6c200..2b1caf1d87 100644 --- a/src/lib/evas/common/evas_text_utils.h +++ b/src/lib/evas/common/evas_text_utils.h @@ -80,6 +80,9 @@ evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst, void evas_common_text_props_content_ref(Evas_Text_Props *props); +void +evas_common_text_props_content_nofree_unref(Evas_Text_Props *props); + void evas_common_text_props_content_unref(Evas_Text_Props *props);