diff --git a/ChangeLog b/ChangeLog index 8389e52de9..3f2e2b5a0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-02-28 Tom Hacohen (TAsn) + + * Evas textblock: Added proper size adjustments for + "high" shaped texts. + 2013-02-28 Mike Blumenkrantz * fix custom states for edje SPACER parts diff --git a/NEWS b/NEWS index 5784262b99..837de78c2e 100644 --- a/NEWS +++ b/NEWS @@ -115,6 +115,7 @@ Improvements: * eina, evas: improved support for 64bits system. * Evas GL engine downscale quality in smooth mode much improved with multisampling up to effectively 16x16 via shaders. * eina: eina_strlcat now work with a NULL source. + * Evas textblock: Added proper size adjustments for "high" shaped texts. Fixes: * Fix a memory leak in ecore_con_dns when using ecore_con_server_connect diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 93899cceaf..31d55b0f97 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -2436,6 +2436,13 @@ _format_dup(Evas_Object *eo_obj, const Evas_Object_Textblock_Format *fmt) +typedef enum +{ + TEXTBLOCK_POSITION_START, + TEXTBLOCK_POSITION_END, + TEXTBLOCK_POSITION_ELSE +} Textblock_Position; + /** * @internal * @typedef Ctxt @@ -2467,6 +2474,7 @@ struct _Ctxt int underline_extend; int have_underline, have_underline2; double align, valign; + Textblock_Position position; Eina_Bool align_auto : 1; Eina_Bool width_changed : 1; }; @@ -2474,6 +2482,7 @@ struct _Ctxt static void _layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Text_Item *ti, Eina_List *rel); static void _text_item_update_sizes(Ctxt *c, Evas_Object_Textblock_Text_Item *ti); static void _layout_do_format(const Evas_Object *eo_obj, Ctxt *c, Evas_Object_Textblock_Format **_fmt, Evas_Object_Textblock_Node_Format *n, int *style_pad_l, int *style_pad_r, int *style_pad_t, int *style_pad_b, Eina_Bool create_item); + /** * @internal * Adjust the ascent/descent of the format and context. @@ -2527,6 +2536,36 @@ _layout_format_ascent_descent_adjust(const Evas_Object *eo_obj, } } +/** + * @internal + * Adjust the ascent/descent of the item and context. + * + * @param maxascent The ascent to update - Not NUL. + * @param maxdescent The descent to update - Not NUL. + * @param it The format to adjust - NOT NULL. + * @param position The position inside the textblock + */ +static void +_layout_item_ascent_descent_adjust(const Evas_Object *eo_obj, + Evas_Coord *maxascent, Evas_Coord *maxdescent, + Evas_Object_Textblock_Item *it, Textblock_Position position) +{ + _layout_format_ascent_descent_adjust(eo_obj, maxascent, maxdescent, it->format); + + if ((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) && + (position == TEXTBLOCK_POSITION_START)) + { + int asc = 0, desc = 0; + evas_common_font_ascent_descent_get((void *) it->format->font.font, + &_ITEM_TEXT(it)->text_props, &asc, &desc); + + if (maxascent && (asc > *maxascent)) + *maxascent = asc; + if (maxdescent && (desc < *maxdescent)) + *maxdescent = desc; + } +} + /** * @internal * Create a new line using the info from the format and update the format @@ -3234,6 +3273,7 @@ loop_advance: static void _layout_line_advance(Ctxt *c, Evas_Object_Textblock_Format *fmt) { + c->position = TEXTBLOCK_POSITION_ELSE; _layout_line_finalize(c, fmt); _layout_line_new(c, fmt); } @@ -4315,9 +4355,8 @@ _layout_par(Ctxt *c) if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT) { - Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it); - _layout_format_ascent_descent_adjust(c->obj, &c->maxascent, - &c->maxdescent, ti->parent.format); + _layout_item_ascent_descent_adjust(c->obj, &c->maxascent, + &c->maxdescent, it, c->position); } else { @@ -4329,8 +4368,8 @@ _layout_par(Ctxt *c) /* If there are no text items yet, calc ascent/descent * according to the current format. */ if (c->maxascent + c->maxdescent == 0) - _layout_format_ascent_descent_adjust(c->obj, &c->maxascent, - &c->maxdescent, it->format); + _layout_item_ascent_descent_adjust(c->obj, &c->maxascent, + &c->maxdescent, it, c->position); _layout_calculate_format_item_size(c->obj, fi, &c->maxascent, &c->maxdescent, &fi->y, &fi->parent.w, &fi->parent.h); @@ -4897,6 +4936,8 @@ _layout(const Evas_Object *eo_obj, int w, int h, int *w_ret, int *h_ret) int par_count = 1; /* Force it to take the first one */ int par_index_pos = 0; + c->position = TEXTBLOCK_POSITION_START; + if (par_index_step == 0) par_index_step = 1; /* Clear all of the index */ @@ -9852,7 +9893,7 @@ _textblock_size_formatted_get(Eo *eo_obj, void *_pd, va_list *list) static void _size_native_calc_line_finalize(const Evas_Object *eo_obj, Eina_List *items, - Evas_Coord *ascent, Evas_Coord *descent, Evas_Coord *w) + Evas_Coord *ascent, Evas_Coord *descent, Evas_Coord *w, Textblock_Position position) { Evas_Object_Textblock_Item *it; Eina_List *i; @@ -9865,8 +9906,8 @@ _size_native_calc_line_finalize(const Evas_Object *eo_obj, Eina_List *items, /* If there are no text items yet, calc ascent/descent * according to the current format. */ if (*ascent + *descent == 0) - _layout_format_ascent_descent_adjust(eo_obj, ascent, descent, - it->format); + _layout_item_ascent_descent_adjust(eo_obj, ascent, descent, + it, position); /* Add margins. */ if (it->format) @@ -9904,6 +9945,7 @@ _size_native_calc_paragraph_size(const Evas_Object *eo_obj, Evas_Object_Textblock_Item *it; Eina_List *line_items = NULL; Evas_Coord w = 0, y = 0, wmax = 0, h = 0, ascent = 0, descent = 0; + Textblock_Position position = TEXTBLOCK_POSITION_START; EINA_LIST_FOREACH(par->logical_items, i, it) { @@ -9915,7 +9957,7 @@ _size_native_calc_paragraph_size(const Evas_Object *eo_obj, _IS_PARAGRAPH_SEPARATOR(o, fi->item))) { _size_native_calc_line_finalize(eo_obj, line_items, &ascent, - &descent, &w); + &descent, &w, position); if (ascent + descent > h) h = ascent + descent; @@ -9925,6 +9967,7 @@ _size_native_calc_paragraph_size(const Evas_Object *eo_obj, wmax = w; h = 0; ascent = descent = 0; + position = TEXTBLOCK_POSITION_ELSE; line_items = eina_list_free(line_items); } else @@ -9933,8 +9976,8 @@ _size_native_calc_paragraph_size(const Evas_Object *eo_obj, /* If there are no text items yet, calc ascent/descent * according to the current format. */ if (it && (ascent + descent == 0)) - _layout_format_ascent_descent_adjust(eo_obj, &ascent, - &descent, it->format); + _layout_item_ascent_descent_adjust(eo_obj, &ascent, + &descent, it, position); _layout_calculate_format_item_size(eo_obj, fi, &ascent, &descent, &fy, &fw, &fh); @@ -9942,12 +9985,12 @@ _size_native_calc_paragraph_size(const Evas_Object *eo_obj, } else { - _layout_format_ascent_descent_adjust(eo_obj, &ascent, - &descent, it->format); + _layout_item_ascent_descent_adjust(eo_obj, &ascent, + &descent, it, position); } } - _size_native_calc_line_finalize(eo_obj, line_items, &ascent, &descent, &w); + _size_native_calc_line_finalize(eo_obj, line_items, &ascent, &descent, &w, position); line_items = eina_list_free(line_items); diff --git a/src/lib/evas/common/evas_font.h b/src/lib/evas/common/evas_font.h index cf867b95d0..205d0f757a 100644 --- a/src/lib/evas/common/evas_font.h +++ b/src/lib/evas/common/evas_font.h @@ -74,6 +74,7 @@ EAPI int evas_common_font_query_pen_coords (RGBA_Font *fn, con EAPI int evas_common_font_query_char_at_coords (RGBA_Font *fn, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch); EAPI int evas_common_font_query_last_up_to_pos (RGBA_Font *fn, const Evas_Text_Props *intl_props, int x, int y); EAPI int evas_common_font_query_run_font_end_get(RGBA_Font *fn, RGBA_Font_Int **script_fi, RGBA_Font_Int **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len); +EAPI void evas_common_font_ascent_descent_get(RGBA_Font *fn, const Evas_Text_Props *text_props, int *ascent, int *descent); void evas_common_font_load_init(void); void evas_common_font_load_shutdown(void); diff --git a/src/lib/evas/common/evas_font_query.c b/src/lib/evas/common/evas_font_query.c index d3f722174c..c87aabfba5 100644 --- a/src/lib/evas/common/evas_font_query.c +++ b/src/lib/evas/common/evas_font_query.c @@ -272,6 +272,46 @@ evas_common_font_query_right_inset(RGBA_Font *fn EINA_UNUSED, const Evas_Text_Pr ); } +/** + * @internal + * Calculate the ascent/descent of a run. This is different from + * evas_common_font_[max]_ascent/descent_get because this one returns the + * actual sizee (i.e including accents), and not just what the font reports. + * + * @param fn the font set to use. + * @param text_props the string object. + * @param[out] ascent the calculated ascent + * @param[out] descent the calculated descent + */ +EAPI void +evas_common_font_ascent_descent_get(RGBA_Font *fn, const Evas_Text_Props *text_props, int *ascent, int *descent) +{ + int asc = 0, desc = 0; + int max_asc, max_desc; + + max_asc = evas_common_font_ascent_get(fn); + max_desc = evas_common_font_descent_get(fn); + + /* FIXME: Not supported yet!!! */ + desc = max_desc; + + EVAS_FONT_WALK_TEXT_INIT(); + EVAS_FONT_WALK_TEXT_START() + { + EVAS_FONT_WALK_TEXT_WORK(); + if (!EVAS_FONT_WALK_IS_VISIBLE) continue; + + if ((EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR) > asc) + { + asc = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR; + } + } + EVAS_FONT_WALK_TEXT_END(); + + if (ascent) *ascent = (asc > max_asc) ? asc : max_asc; + if (descent) *descent = (desc < max_desc) ? desc : max_desc; +} + /** * @internal * Calculate the size of the string (width and height).