#ifdef BIDI_SUPPORT
#include <fribidi/fribidi.h>
+/**
+ * @internal
+ * @addtogroup Evas_Utils
+ *
+ * @{
+ */
+/**
+ * @internal
+ * @addtogroup Evas_BiDi
+ *
+ * @{
+ */
+/**
+ * @internal
+ * @def _SAFE_FREE(x)
+ * checks if x is not NULL, if it's not, it's freed and set to NULL.
+ */
#define _SAFE_FREE(x) \
do { \
if (x) \
} \
} while(0)
+/**
+ * @internal
+ * Checks if the string has RTL characters.
+ *
+ * @param str The string to be checked
+ * @return #EINA_TRUE if true, #EINA_FALSE otherwise.
+ */
Eina_Bool
evas_bidi_is_rtl_str(const Eina_Unicode *str)
{
int i = 0;
int ch;
EvasBiDiCharType type;
-
+
if (!str)
return EINA_FALSE;
for ( ; *str ; str++)
{
type = fribidi_get_bidi_type(*str);
- if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type))
+ if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type))
{
return EINA_TRUE;
}
return EINA_FALSE;
}
+/**
+ * @internal
+ * Shapes the string ustr according to the bidi properties.
+ *
+ * @param str The string to shape
+ * @param bidi_props the bidi props to shaped according.
+ * @param len the length of th string.
+ * @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)
{
join_types = (EvasBiDiJoiningType *) malloc(sizeof(EvasBiDiJoiningType) * len);
if (!join_types)
{
- return -2;
+ return EINA_FALSE;
}
fribidi_get_joining_types(ustr, len, join_types);
return EINA_TRUE;
}
+/**
+ * @internal
+ * Updates the bidi properties according to ustr. First checks to see if the
+ * passed has rtl chars, if not, it cleans intl_props and returns.
+ * Otherwise, it essentially frees the old fields, allocates new fields, and
+ * populates them.
+ * On error: bidi_props is cleaned.
+ *
+ * @param ustr The string to update according to.
+ * @param bidi_props the bidi_props to update.
+ * @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)
{
len = eina_unicode_strlen(ustr);
- /* Prep work for reordering */
+ /* Prep work for reordering */
char_types = (EvasBiDiCharType *) malloc(sizeof(EvasBiDiCharType) * len);
if (!char_types)
{
len = -2;
goto cleanup;
}
-
-
+
+
/* clean up */
- if (bidi_props->embedding_levels)
+ if (bidi_props->embedding_levels)
{
free(bidi_props->embedding_levels);
}
bidi_props->embedding_levels = embedding_levels;
/* clean up */
-
- if (bidi_props->char_types)
+
+ if (bidi_props->char_types)
{
free(bidi_props->char_types);
}
bidi_props->char_types = char_types;
-
+
return len;
/* Cleanup */
return len;
}
-int
+/**
+ * @internal
+ * Reorders ustr according to the bidi props.
+ *
+ * @param ustr the string to reorder.
+ * @param intl_props the intl properties to rerorder according to.
+ * @param _v_to_l The visual to logical map to populate - if NULL it won't populate it.
+ * @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)
{
EvasBiDiStrIndex *v_to_l = NULL;
size_t len;
if (!EVAS_BIDI_IS_BIDI_PROP(intl_props->props))
- return 0;
+ return EINA_FALSE;
len = eina_unicode_strlen(ustr);
/* Shaping must be done *BEFORE* breaking to lines so there's no choice but
doing it in textblock. */
- if (!fribidi_reorder_line (FRIBIDI_FLAGS_DEFAULT, intl_props->props->char_types + intl_props->start,
- len, 0, intl_props->props->direction,
- intl_props->props->embedding_levels + intl_props->start, ustr, v_to_l))
+ if (!fribidi_reorder_line (FRIBIDI_FLAGS_DEFAULT,
+ intl_props->props->char_types + intl_props->start,
+ len, 0, intl_props->props->direction,
+ intl_props->props->embedding_levels + intl_props->start,
+ ustr, v_to_l))
{
goto error;
}
-
- return 0;
+
+ return EINA_FALSE;
/* ERROR HANDLING */
error:
_SAFE_FREE(v_to_l);
- return 1;
+ return EINA_TRUE;
}
+/**
+ * @internal
+ * Returns the visual string index from the logical string index.
+ *
+ * @param v_to_l the visual to logical map
+ * @param len the length of the map.
+ * @param position the position to convert.
+ * @return on success the visual position, on failure the same position.
+ */
EvasBiDiStrIndex
evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDiStrIndex position)
{
EvasBiDiStrIndex *ind;
if (position >= len || !v_to_l)
return position;
-
- for (i = 0, ind = v_to_l ; i < len ; i++, ind++)
+
+ for (i = 0, ind = v_to_l ; i < len ; i++, ind++)
{
if (*ind == position)
{
return position;
}
+/**
+ * @internal
+ * Checks if the char is rtl oriented. I.e even a neutral char can become rtl
+ * if surrounded by rtl chars.
+ *
+ * @param embedded_level_list the bidi embedding list.
+ * @param index the index of the string.
+ * @return #EINA_TRUE if true, #EINA_FALSE otherwise.
+ */
Eina_Bool
evas_bidi_is_rtl_char(EvasBiDiLevel *embedded_level_list, EvasBiDiStrIndex index)
{
return (FRIBIDI_IS_RTL(embedded_level_list[index])) ? EINA_TRUE : EINA_FALSE;
}
+/**
+ * @internal
+ * Cleans the paragraph properties.
+ *
+ * @param bidi_props the properties to clean.
+ */
void
evas_bidi_paragraph_props_clean(Evas_BiDi_Paragraph_Props *bidi_props)
{
_SAFE_FREE(bidi_props->embedding_levels);
_SAFE_FREE(bidi_props->char_types);
}
+
+/**
+ * @internal
+ * Cleans the bidi properties.
+ *
+ * @param bidi_props the properties to clean.
+ */
void
evas_bidi_props_clean(Evas_BiDi_Props *bidi_props)
{
evas_bidi_paragraph_props_clean(bidi_props->props);
bidi_props->props = NULL;
}
+/**
+ * @}
+ */
+/**
+ * @}
+ */
#endif
+
#ifndef _EVAS_BIDI_UTILS
#define _EVAS_BIDI_UTILS
+/**
+ * @internal
+ * @addtogroup Evas_Utils
+ *
+ * @{
+ */
+/**
+ * @internal
+ * @defgroup Evas_BiDi Evas BiDi utility functions
+ *
+ * This set of functions and types helps evas handle BiDi strings correctly.
+ * @todo Document types, structures and macros.
+ *
+ * @{
+ */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
typedef struct _Evas_BiDi_Paragraph_Props Evas_BiDi_Paragraph_Props;
typedef struct _Evas_BiDi_Props Evas_BiDi_Props;
-/* This structure defines a set of properties of a BiDi string. In case of a
+/* This structure defines a set of properties of a BiDi string. In case of a
* non-bidi string, all values should be NULL.
* To check if a structure describes a bidi string or not, use the macro
* EVAS_BIDI_IS_BIDI_PROP. RTL-only strings are also treated as bidi ATM.
# define evas_bidi_position_visual_to_logical(list, position) \
(list) ? list[position] : position;
-/* Gets a v_to_l list, it's len and a logical character index, and returns the
- * the visual index of that character.
- */
EvasBiDiStrIndex
evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDiStrIndex position);
-/* Returns true if the string has rtl characters, false otherwise */
Eina_Bool
evas_bidi_is_rtl_str(const Eina_Unicode *str);
-/* Returns true if the embedding level of the index is rtl, false otherwise */
Eina_Bool
evas_bidi_is_rtl_char(EvasBiDiLevel *embedded_level_list, EvasBiDiStrIndex index);
-/* Overallocates a bit, if anyone cares, he should realloc, though usually,
- * the string get freed very fast so there's really no need to care about it
- * (rellaoc-ing is slower than not)
- */
-int
+Eina_Bool
evas_bidi_props_reorder_line(Eina_Unicode *text, const Evas_BiDi_Props *intl_props, EvasBiDiStrIndex **_v_to_l);
-/* Updates the international properties according to the text. First checks to see
- * if the text in question has rtl chars, if not, it cleans intl_props and returns.
- * Otherwise, it essentially frees the old fields, allocates new fields, and
- * populates them.
- * On error, intl_props gets cleaned.
- * Return value: the length of the string.
- */
int
evas_bidi_update_props(const Eina_Unicode *text, Evas_BiDi_Paragraph_Props *intl_props) EINA_ARG_NONNULL(1, 2);
-/* Actually shape the string */
Eina_Bool
evas_bidi_shape_string(Eina_Unicode *ustr, const Evas_BiDi_Props *intl_props, size_t len);
-/* Cleans and frees the international properties. - Just the content, not the
- * poitner itself.
- */
+
void
evas_bidi_props_clean(Evas_BiDi_Props *intl_props) EINA_ARG_NONNULL(1);
+
void
evas_bidi_paragraph_props_clean(Evas_BiDi_Paragraph_Props *bidi_props) EINA_ARG_NONNULL(1);
#endif
+/**
+ * @}
+ */
+/**
+ * @}
+ */
#endif
+