From: Enlightenment S. <no-...@en...> - 2010-08-16 12:51:40
|
Log: Evas bidi: Added saftey conversions to make sure FriBidiChar and Eina_Unicode are really the same size. Author: tasn Date: 2010-08-16 05:51:30 -0700 (Mon, 16 Aug 2010) New Revision: 51208 Modified: trunk/evas/src/lib/engines/common/evas_bidi_utils.c Modified: trunk/evas/src/lib/engines/common/evas_bidi_utils.c =================================================================== --- trunk/evas/src/lib/engines/common/evas_bidi_utils.c 2010-08-16 12:50:32 UTC (rev 51207) +++ trunk/evas/src/lib/engines/common/evas_bidi_utils.c 2010-08-16 12:51:30 UTC (rev 51208) @@ -36,6 +36,30 @@ } \ } while(0) +/* Convert bidichar to eina_unicode assume both are valid pointers */ +static Eina_Unicode * +_evas_bidi_fribidichar_to_unicode(Eina_Unicode *dest, const FriBidiChar *src) +{ + Eina_Unicode *ret = dest; + + while (*src) + *dest++ = *src++; + *dest = 0; + return ret; +} + +/* Convert eina_unicode to bidi_char assume both are valid pointers */ +static FriBidiChar * +_evas_bidi_unicode_to_fribidichar(FriBidiChar *dest, const Eina_Unicode *src) +{ + FriBidiChar *ret = dest; + + while (*src) + *dest++ = *src++; + *dest = 0; + return ret; +} + /** * @internal * Checks if the string has RTL characters. @@ -53,7 +77,7 @@ for ( ; *str ; str++) { - type = fribidi_get_bidi_type(*str); + type = fribidi_get_bidi_type((FriBidiChar) *str); if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type)) { return EINA_TRUE; @@ -72,11 +96,27 @@ * @return #EINA_TRUE on success, #EINA_FALSE otherwise. */ Eina_Bool -evas_bidi_shape_string(Eina_Unicode *ustr, const Evas_BiDi_Props *bidi_props, size_t len) +evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Props *bidi_props, size_t len) { + FriBidiChar *ustr, *base_ustr = NULL; + if (!EVAS_BIDI_IS_BIDI_PROP(bidi_props->props)) return EINA_FALSE; + /* The size of fribidichar is different than eina_unicode, convert */ + /*FIXME: Make this comparison at compile time and compile out + * unwanted code. - In all of this source file. */ + if (sizeof(Eina_Unicode) != sizeof(FriBidiChar)) + { + base_ustr = ustr = calloc(len + 1, sizeof(FriBidiChar)); + ustr = _evas_bidi_unicode_to_fribidichar(ustr, eina_ustr); + } + else + { + ustr = (FriBidiChar *) eina_ustr; + } + + EvasBiDiJoiningType *join_types = NULL; join_types = (EvasBiDiJoiningType *) malloc(sizeof(EvasBiDiJoiningType) * len); if (!join_types) @@ -93,6 +133,13 @@ bidi_props->props->embedding_levels + bidi_props->start, len, join_types, ustr); if (join_types) free(join_types); + + /* Convert back */ + if (sizeof(Eina_Unicode) != sizeof(FriBidiChar)) + { + eina_ustr = _evas_bidi_fribidichar_to_unicode(eina_ustr, ustr); + if (base_ustr) free(base_ustr); + } return EINA_TRUE; } @@ -109,23 +156,38 @@ * @return returns the length of the string on success, a negative value on error. */ int -evas_bidi_update_props(const Eina_Unicode *ustr, Evas_BiDi_Paragraph_Props *bidi_props) +evas_bidi_update_props(const Eina_Unicode *eina_ustr, Evas_BiDi_Paragraph_Props *bidi_props) { EvasBiDiCharType *char_types = NULL; EvasBiDiLevel *embedding_levels = NULL; + const FriBidiChar *ustr; + FriBidiChar *base_ustr = NULL; size_t len; - if (!ustr) + if (!eina_ustr) return -2; - if (!evas_bidi_is_rtl_str(ustr)) /* No need to handle bidi */ + + len = eina_unicode_strlen(eina_ustr); + /* The size of fribidichar s different than eina_unicode, convert */ + if (sizeof(Eina_Unicode) != sizeof(FriBidiChar)) { + base_ustr = calloc(len + 1, sizeof(FriBidiChar)); + base_ustr = _evas_bidi_unicode_to_fribidichar(base_ustr, eina_ustr); + ustr = base_ustr; + } + else + { + ustr = (const FriBidiChar *) eina_ustr; + } + + + if (!evas_bidi_is_rtl_str(eina_ustr)) /* No need to handle bidi */ + { len = -1; goto cleanup; } - len = eina_unicode_strlen(ustr); - /* Prep work for reordering */ char_types = (EvasBiDiCharType *) malloc(sizeof(EvasBiDiCharType) * len); if (!char_types) @@ -163,13 +225,16 @@ } bidi_props->char_types = char_types; + if (base_ustr) free(base_ustr); + return len; /* Cleanup */ cleanup: if (char_types) free(char_types); if (embedding_levels) free(embedding_levels); + if (base_ustr) free(base_ustr); evas_bidi_paragraph_props_clean(bidi_props); /*Mark that we don't need bidi handling */ return len; } @@ -184,16 +249,28 @@ * @return #EINA_FALSE on success, #EINA_TRUE on error. */ Eina_Bool -evas_bidi_props_reorder_line(Eina_Unicode *ustr, const Evas_BiDi_Props *intl_props, EvasBiDiStrIndex **_v_to_l) +evas_bidi_props_reorder_line(Eina_Unicode *eina_ustr, const Evas_BiDi_Props *intl_props, EvasBiDiStrIndex **_v_to_l) { EvasBiDiStrIndex *v_to_l = NULL; + FriBidiChar *ustr, *base_ustr = NULL; size_t len; if (!EVAS_BIDI_IS_BIDI_PROP(intl_props->props)) return EINA_FALSE; - len = eina_unicode_strlen(ustr); + len = eina_unicode_strlen(eina_ustr); + /* The size of fribidichar is different than eina_unicode, convert */ + if (sizeof(Eina_Unicode) != sizeof(FriBidiChar)) + { + base_ustr = ustr = calloc(len + 1, sizeof(FriBidiChar)); + ustr = _evas_bidi_unicode_to_fribidichar(ustr, eina_ustr); + } + else + { + ustr = (FriBidiChar *) eina_ustr; + } + if (_v_to_l) { int i; v_to_l = *_v_to_l = calloc(len, sizeof(EvasBiDiStrIndex)); @@ -220,9 +297,16 @@ } + /* The size of fribidichar is different than eina_unicode, convert */ + if (sizeof(Eina_Unicode) != sizeof(FriBidiChar)) + { + eina_ustr = _evas_bidi_fribidichar_to_unicode(eina_ustr, base_ustr); + free(base_ustr); + } return EINA_FALSE; /* ERROR HANDLING */ error: + if (base_ustr) free(base_ustr); _SAFE_FREE(v_to_l); return EINA_TRUE; } |