From 440bb7c23ca9bf25165041617d2d1717e0b2584a Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 12 Jan 2013 08:40:46 +0000 Subject: [PATCH] cut down textprop size a bit... 72 -> 64bytes. if we can wrap tp->start/len/text_offset/text_len read/wrtie in access funcs. so we can special case where: 1. start == text_offset == 0 && len == text_len == 1 2. start == text_offset == 0 && len == text_len < 65536 3. start == text_offset == 0 && len == text_len < 256 SVN revision: 82692 --- src/lib/evas/canvas/evas_object_text.c | 2 +- src/lib/evas/canvas/evas_object_textblock.c | 12 +-- src/lib/evas/common/evas_font_default_walk.x | 6 +- src/lib/evas/common/evas_font_query.c | 16 ++-- src/lib/evas/common/evas_text_utils.c | 20 ++--- src/lib/evas/common/evas_text_utils.h | 92 +++++++++++++++----- 6 files changed, 100 insertions(+), 48 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c index 459e1a9ed7..3bc185a2da 100644 --- a/src/lib/evas/canvas/evas_object_text.c +++ b/src/lib/evas/canvas/evas_object_text.c @@ -1071,7 +1071,7 @@ _text_direction_get(Eo *eo_obj EINA_UNUSED, void *_pd, va_list *list) { Evas_BiDi_Direction *bidi_dir = va_arg(*list, Evas_BiDi_Direction *); const Evas_Object_Text *o = _pd; - *bidi_dir = o->items ? o->items->text_props.bidi.dir : EVAS_BIDI_DIRECTION_NEUTRAL; + *bidi_dir = o->items ? o->items->text_props.bidi_dir : EVAS_BIDI_DIRECTION_NEUTRAL; } EAPI Evas_Coord diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 9b2382d121..2249111457 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -8957,7 +8957,7 @@ evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord Evas_Object_Textblock_Item *it; _find_layout_item_match(dir_cur, &ln, &it); if ((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) && - (_ITEM_TEXT(it)->text_props.bidi.dir == + (_ITEM_TEXT(it)->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL)) is_rtl = EINA_TRUE; else if ((it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) && @@ -8987,7 +8987,7 @@ evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord Evas_Object_Textblock_Item *it; _find_layout_item_match(dir_cur, &ln, &it); if ((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) && - (_ITEM_TEXT(it)->text_props.bidi.dir == + (_ITEM_TEXT(it)->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL)) is_rtl = EINA_TRUE; else if ((it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) && @@ -9028,7 +9028,7 @@ evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord Evas_Object_Textblock_Item *it; _find_layout_item_match(dir_cur, &ln, &it); if ((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) && - (_ITEM_TEXT(it)->text_props.bidi.dir == + (_ITEM_TEXT(it)->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL)) is_rtl = EINA_TRUE; else if ((it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) && @@ -9435,7 +9435,7 @@ _evas_textblock_range_calc_x_w(const Evas_Object_Textblock_Item *it, { #ifdef BIDI_SUPPORT if (((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) && - _ITEM_TEXT(it)->text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL) + _ITEM_TEXT(it)->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL) || ((it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) && _ITEM_FORMAT(it)->bidi_dir == EVAS_BIDI_DIRECTION_RTL)) @@ -9453,7 +9453,7 @@ _evas_textblock_range_calc_x_w(const Evas_Object_Textblock_Item *it, { #ifdef BIDI_SUPPORT if (((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) && - _ITEM_TEXT(it)->text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL) + _ITEM_TEXT(it)->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL) || ((it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) && _ITEM_FORMAT(it)->bidi_dir == EVAS_BIDI_DIRECTION_RTL)) @@ -9589,7 +9589,7 @@ _evas_textblock_cursor_range_in_line_geometry_get( } #ifdef BIDI_SUPPORT - if (ti->text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (ti->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL) { x = x1 + w1; w = x2 + w2 - x; diff --git a/src/lib/evas/common/evas_font_default_walk.x b/src/lib/evas/common/evas_font_default_walk.x index 7636201160..40d11bcf00 100644 --- a/src/lib/evas/common/evas_font_default_walk.x +++ b/src/lib/evas/common/evas_font_default_walk.x @@ -77,18 +77,18 @@ # define EVAS_FONT_WALK_X_OFF 0 # define EVAS_FONT_WALK_Y_OFF 0 # define EVAS_FONT_WALK_POS \ - ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \ + ((text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) ? \ (text_props->len - char_index - 1) : \ (char_index)) # define EVAS_FONT_WALK_POS_NEXT \ ((!EVAS_FONT_WALK_IS_LAST) ? \ - ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \ + ((text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) ? \ text_props->len - char_index - 2 \ : (char_index + 1)) : \ EVAS_FONT_WALK_POS) # define EVAS_FONT_WALK_POS_PREV \ ((char_index > 0) ? \ - ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \ + ((text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) ? \ text_props->len - char_index \ : (char_index - 1)) : \ EVAS_FONT_WALK_POS) diff --git a/src/lib/evas/common/evas_font_query.c b/src/lib/evas/common/evas_font_query.c index 32182bd963..a5dcbcb84b 100644 --- a/src/lib/evas/common/evas_font_query.c +++ b/src/lib/evas/common/evas_font_query.c @@ -392,7 +392,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Evas_Text_Props *text_pr /* if it's rtl then the location is the left of the string, * otherwise, the right. */ #ifdef BIDI_SUPPORT - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { if (cx) *cx = 0; if (ch) *ch = asc + desc; @@ -433,7 +433,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Evas_Text_Props *text_pr last_end = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR + EVAS_FONT_WALK_WIDTH; /* we need to see if the char at the visual position is the char wanted */ - if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) && + if ((text_props->bidi_dir == EVAS_BIDI_DIRECTION_LTR) && (EVAS_FONT_WALK_POS <= (size_t) position) && ((((size_t) position) < EVAS_FONT_WALK_POS_NEXT) || (EVAS_FONT_WALK_IS_LAST))) @@ -445,7 +445,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Evas_Text_Props *text_pr #endif item_pos = position - EVAS_FONT_WALK_POS + 1; } - else if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && + else if ((text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) && ((EVAS_FONT_WALK_POS_PREV > (size_t) position) || (EVAS_FONT_WALK_IS_FIRST)) && (((size_t) position) >= EVAS_FONT_WALK_POS)) @@ -528,7 +528,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Evas_Text_Props *text_pro /* if it's rtl then the location is the left of the string, * otherwise, the right. */ #ifdef BIDI_SUPPORT - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { if (cpen_x) *cpen_x = 0; if (ch) *ch = asc + desc; @@ -564,7 +564,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Evas_Text_Props *text_pro } last_is_visible = EVAS_FONT_WALK_IS_VISIBLE; - if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) && + if ((text_props->bidi_dir == EVAS_BIDI_DIRECTION_LTR) && (EVAS_FONT_WALK_POS <= (size_t) position) && ((((size_t) position) < EVAS_FONT_WALK_POS_NEXT) || (EVAS_FONT_WALK_IS_LAST))) @@ -576,7 +576,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Evas_Text_Props *text_pro #endif item_pos = position - EVAS_FONT_WALK_POS + 1; } - else if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && + else if ((text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) && ((EVAS_FONT_WALK_POS_PREV > (size_t) position) || (EVAS_FONT_WALK_IS_FIRST)) && (((size_t) position) >= EVAS_FONT_WALK_POS)) @@ -686,7 +686,7 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Evas_Text_Props *text Evas_Coord cluster_adv; cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start; - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) + if (text_props->bidi_dir == EVAS_BIDI_DIRECTION_LTR) { double part; part = cluster_adv / items; @@ -734,7 +734,7 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props *text desc = evas_common_font_max_descent_get(fn); #ifdef BIDI_SUPPORT - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { Evas_Font_Glyph_Info *gli = NULL; Evas_Coord full_adv = 0, pen_x = 0, start_pen = 0; diff --git a/src/lib/evas/common/evas_text_utils.c b/src/lib/evas/common/evas_text_utils.c index e6e015e1f0..7dc9485378 100644 --- a/src/lib/evas/common/evas_text_utils.c +++ b/src/lib/evas/common/evas_text_utils.c @@ -12,14 +12,14 @@ evas_common_text_props_bidi_set(Evas_Text_Props *props, Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start) { #ifdef BIDI_SUPPORT - props->bidi.dir = (evas_bidi_is_rtl_char( + props->bidi_dir = (evas_bidi_is_rtl_char( bidi_par_props, 0, start)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR; #else (void) start; (void) bidi_par_props; - props->bidi.dir = EVAS_BIDI_DIRECTION_LTR; + props->bidi_dir = EVAS_BIDI_DIRECTION_LTR; #endif PROPS_CHANGE(props); } @@ -142,7 +142,7 @@ evas_common_text_props_cluster_next(const Evas_Text_Props *props, int pos) { Eina_Bool right; /* Move right if we are in a non-rtl text */ - right = (props->bidi.dir != EVAS_BIDI_DIRECTION_RTL); + right = (props->bidi_dir != EVAS_BIDI_DIRECTION_RTL); return _evas_common_text_props_cluster_move(props, pos, right); } @@ -151,7 +151,7 @@ evas_common_text_props_cluster_prev(const Evas_Text_Props *props, int pos) { Eina_Bool right; /* Move right if we are in an rtl text */ - right = (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL); + right = (props->bidi_dir == EVAS_BIDI_DIRECTION_RTL); return _evas_common_text_props_cluster_move(props, pos, right); } @@ -173,7 +173,7 @@ evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff) else mid = (min + max) / 2; - if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { /* Monotonic in a descending order */ do @@ -211,7 +211,7 @@ evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff) return -1; ot_info += mid; - if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { /* Walk to the last one of the same cluster */ for ( ; mid < (int) props->len ; mid++, ot_info++) @@ -266,7 +266,7 @@ evas_common_text_props_split(Evas_Text_Props *base, #endif evas_common_text_props_content_copy_and_ref(ext, base); - if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (base->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { ext->start = base->start; ext->len = cutoff + 1; @@ -309,7 +309,7 @@ evas_common_text_props_merge(Evas_Text_Props *item1, ERR("tried merge back items that weren't together in the first place."); return; } - if (item1->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (item1->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { item1->start = item2->start; } @@ -406,7 +406,7 @@ _content_create_regular(RGBA_Font_Int *fi, const Eina_Unicode *text, Eina_Unicode *base_str = NULL; if (mode == EVAS_TEXT_PROPS_MODE_SHAPE) { - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { text = base_str = eina_unicode_strndup(text, len); evas_bidi_shape_string(base_str, par_props, par_pos, len); @@ -427,7 +427,7 @@ _content_create_regular(RGBA_Font_Int *fi, const Eina_Unicode *text, text_props->info->glyph = calloc(len, sizeof(Evas_Font_Glyph_Info)); - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (text_props->bidi_dir == EVAS_BIDI_DIRECTION_RTL) { text += len - 1; adv_d = -1; diff --git a/src/lib/evas/common/evas_text_utils.h b/src/lib/evas/common/evas_text_utils.h index 36a8895a37..f2f65a396b 100644 --- a/src/lib/evas/common/evas_text_utils.h +++ b/src/lib/evas/common/evas_text_utils.h @@ -1,7 +1,11 @@ #ifndef _EVAS_TEXT_UTILS_H # define _EVAS_TEXT_UTILS_H + typedef struct _Evas_Text_Props Evas_Text_Props; +// special case props +typedef struct _Evas_Text_Props_One Evas_Text_Props_One; + typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info; typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info; @@ -29,42 +33,90 @@ struct _Evas_Glyph_Array struct _Evas_Text_Props { + Evas_Text_Props_Info *info; // 8/4 + Evas_Glyph_Array *glyphs; // 8/4 + void *font_instance; // 8/4 /* Start and len represent the start offset and the length in the * glyphs_info and ot_data fields, they are both internal */ - size_t start; - size_t len; - size_t text_offset; /* The text offset from the start of the info */ - size_t text_len; /* The length of the original text */ - Evas_BiDi_Props bidi; - Evas_Script_Type script; - Evas_Text_Props_Info *info; - void *font_instance; + // i only wonder if generation needs 32bits... :) + int generation; // 4 +// Evas_BiDi_Props bidi; // 4 // bidi.dir == enum +// Evas_Script_Type script; // 4 // enum +// Eina_Bool changed : 1; // 1 +// Eina_Bool prepare : 1; +// // +3 pad +// ** the below saves 8 bytes (72 -> 64 on 64bit) + Evas_BiDi_Direction bidi_dir : 2; // 2 (enough for values) + Evas_Script_Type script : 7; // cont (enough for values) + Eina_Bool changed : 1; // cont (bool) + Eina_Bool prepare : 1; // cont (bool) + // we have space here for at LEAST 5 bits (round up to 2 bytes) but due + // to common padding we actually can add 5 + 16 (21) more bits for free + Eina_Bool szlen_mode : 5; // use 5 of he 21 bits +// this can go here as the above is nicely aligned.... + // this is really big... 32 bytes. MOSt of the time the following... + // start == text_offset == 0 AND len == text_len == smallish value (8 or + // 16 bit is enough to store it most of the time). + size_t start; // 8/4 + size_t len; // 8/4 + size_t text_offset; // 8/4 /* The text offset from the start of the info */ + size_t text_len; // 8/4 /* The length of the original text */ +}; - Evas_Glyph_Array *glyphs; +#define EVAS_TP_SZLEN_FULL 0 +#define EVAS_TP_SZLEN_ONE 1 - int generation; - Eina_Bool changed : 1; - Eina_Bool prepare : 1; +// special case textprop for ONE char! should use this for textgrid but +// we have to modify every bit of code that usea a textprop to go thru a +// getter or setter etc. etc. +struct _Evas_Text_Props_One +{ + Evas_Text_Props_Info *info; // 8/4 + Evas_Glyph_Array *glyphs; // 8/4 + void *font_instance; // 8/4 + /* Start and len represent the start offset and the length in the + * glyphs_info and ot_data fields, they are both internal */ + // i only wonder if generation needs 32bits... :) + int generation; // 4 +// Evas_BiDi_Props bidi; // 4 // bidi.dir == enum +// Evas_Script_Type script; // 4 // enum +// Eina_Bool changed : 1; // 1 +// Eina_Bool prepare : 1; +// // +3 pad +// ** the below saves 8 bytes (72 -> 64 on 64bit) + Evas_BiDi_Direction bidi_dir : 2; // 2 (enough for values) + Evas_Script_Type script : 7; // cont (enough for values) + Eina_Bool changed : 1; // cont (bool) + Eina_Bool prepare : 1; // cont (bool) + // we have space here for at LEAST 5 bits (round up to 2 bytes) but due + // to common padding we actually can add 5 + 16 (21) more bits for free + Eina_Bool szlen_mode : 5; // use 5 of he 21 bits }; struct _Evas_Text_Props_Info { - unsigned int refcount; - Evas_Font_Glyph_Info *glyph; - Evas_Font_OT_Info *ot; + Evas_Font_Glyph_Info *glyph; // 8/4 + Evas_Font_OT_Info *ot; // 8/4 + unsigned int refcount; // 4 }; /* Sorted in visual order when created */ struct _Evas_Font_Glyph_Info { - unsigned int index; /* Should conform to FT */ - Evas_Coord x_bear; + unsigned int index; // 4 /* Should conform to FT */ +#if 1 + // done with shorts to save space... if we need 32k or bigger glyphs and + // relative layout info... worry then. + short x_bear, y_bear, width, pen_after; // 8 +#else + Evas_Coord x_bear; // 4 /* This one is rarely used, only in draw, in which we already get the glyph * so it doesn't really save time. Leaving it here just so no one will * add it thinking it was accidentally skipped */ - Evas_Coord y_bear; - Evas_Coord width; - Evas_Coord pen_after; + Evas_Coord y_bear; // 4 + Evas_Coord width; // 4 + Evas_Coord pen_after; // 4 +#endif }; void