Evas text/textblock: Add setting bidi_delimiter API.

SVN revision: 58669
This commit is contained in:
Tom Hacohen 2011-04-14 15:34:01 +00:00
parent cb90b07d81
commit f5e7165a65
5 changed files with 177 additions and 7 deletions

View File

@ -5301,6 +5301,32 @@ EAPI void evas_object_text_font_get (const Evas_Object *obj
*/
EAPI void evas_object_text_text_set (Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
/**
* @brief Sets the BiDi delimiters used in the textblock.
*
* BiDi delimiters are use for in-paragraph separation of bidi segments. This
* is useful for example in recipients fields of e-mail clients where bidi
* oddities can occur when mixing rtl and ltr.
*
* @param obj The given text object.
* @param delim A null terminated string of delimiters, e.g ",|".
* @since 1.1.0
*/
EAPI void evas_object_text_bidi_delimiters_set(Evas_Object *obj, const char *delim);
/**
* @brief Gets the BiDi delimiters used in the textblock.
*
* BiDi delimiters are use for in-paragraph separation of bidi segments. This
* is useful for example in recipients fields of e-mail clients where bidi
* oddities can occur when mixing rtl and ltr.
*
* @param obj The given text object.
* @return A null terminated string of delimiters, e.g ",|". If empty, returns NULL.
* @since 1.1.0
*/
EAPI const char *evas_object_text_bidi_delimiters_get(const Evas_Object *obj);
/**
* Retrieves the text currently being displayed by the given evas text object.
* @param obj The given evas text object.
@ -5596,6 +5622,31 @@ EAPI void evas_object_textblock_valign_set(Evas_Object *
*/
EAPI double evas_object_textblock_valign_get(const Evas_Object *obj);
/**
* @brief Sets the BiDi delimiters used in the textblock.
*
* BiDi delimiters are use for in-paragraph separation of bidi segments. This
* is useful for example in recipients fields of e-mail clients where bidi
* oddities can occur when mixing rtl and ltr.
*
* @param obj The given textblock object.
* @param delim A null terminated string of delimiters, e.g ",|".
* @since 1.1.0
*/
EAPI void evas_object_textblock_bidi_delimiters_set(Evas_Object *obj, const char *delim);
/**
* @brief Gets the BiDi delimiters used in the textblock.
*
* BiDi delimiters are use for in-paragraph separation of bidi segments. This
* is useful for example in recipients fields of e-mail clients where bidi
* oddities can occur when mixing rtl and ltr.
*
* @param obj The given textblock object.
* @return A null terminated string of delimiters, e.g ",|". If empty, returns NULL.
* @since 1.1.0
*/
EAPI const char *evas_object_textblock_bidi_delimiters_get(const Evas_Object *obj);
/**
* @brief Sets newline mode. When true, newline character will behave

View File

@ -31,6 +31,7 @@ struct _Evas_Object_Text
float ascent, descent;
float max_ascent, max_descent;
Evas_BiDi_Paragraph_Props *bidi_par_props;
const char *bidi_delimiters;
Evas_Object_Text_Item *items;
void *engine_data;
@ -562,9 +563,13 @@ _evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, const Eina_Unico
int cutoff;
int len = eina_unicode_strlen(text);
#ifdef BIDI_SUPPORT
int *segment_idxs = NULL;
if (o->bidi_delimiters)
segment_idxs = evas_bidi_segment_idxs_get(text, o->bidi_delimiters);
evas_bidi_paragraph_props_unref(o->bidi_par_props);
o->bidi_par_props = evas_bidi_paragraph_props_get(text, len, NULL);
o->bidi_par_props = evas_bidi_paragraph_props_get(text, len, segment_idxs);
evas_bidi_props_reorder_line(NULL, 0, len, o->bidi_par_props, &v_to_l);
if (segment_idxs) free(segment_idxs);
#endif
visual_pos = pos = 0;
@ -662,6 +667,39 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text)
if (text) free(text);
}
EAPI void
evas_object_text_bidi_delimiters_set(Evas_Object *obj, const char *delim)
{
Evas_Object_Text *o;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return;
MAGIC_CHECK_END();
o = (Evas_Object_Text *)(obj->object_data);
MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
return;
MAGIC_CHECK_END();
eina_stringshare_replace(&o->bidi_delimiters, delim);
}
EAPI const char *
evas_object_text_bidi_delimiters_get(const Evas_Object *obj)
{
Evas_Object_Text *o;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return NULL;
MAGIC_CHECK_END();
o = (Evas_Object_Text *)(obj->object_data);
MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
return NULL;
MAGIC_CHECK_END();
return o->bidi_delimiters;
}
EAPI const char *
evas_object_text_text_get(const Evas_Object *obj)
{

View File

@ -377,6 +377,7 @@ struct _Evas_Object_Textblock
char *markup_text;
void *engine_data;
const char *repch;
const char *bidi_delimiters;
struct {
int w, h;
unsigned char valid : 1;
@ -1850,15 +1851,23 @@ _layout_paragraph_new(Ctxt *c, Evas_Object_Textblock_Node_Text *n,
* @param par The paragraph to update
*/
static inline void
_layout_update_bidi_props(Evas_Object_Textblock_Paragraph *par)
_layout_update_bidi_props(const Evas_Object_Textblock *o,
Evas_Object_Textblock_Paragraph *par)
{
if (par->text_node)
{
const Eina_Unicode *text;
int *segment_idxs = NULL;
text = eina_ustrbuf_string_get(par->text_node->unicode);
if (o->bidi_delimiters)
segment_idxs = evas_bidi_segment_idxs_get(text, o->bidi_delimiters);
evas_bidi_paragraph_props_unref(par->bidi_props);
par->bidi_props = evas_bidi_paragraph_props_get(
eina_ustrbuf_string_get(par->text_node->unicode),
par->bidi_props = evas_bidi_paragraph_props_get(text,
eina_ustrbuf_length_get(par->text_node->unicode),
NULL);
segment_idxs);
if (segment_idxs) free(segment_idxs);
}
}
#endif
@ -3642,7 +3651,7 @@ _layout(const Evas_Object *obj, int calc_only, int w, int h, int *w_ret, int *h_
}
#ifdef BIDI_SUPPORT
_layout_update_bidi_props(c->par);
_layout_update_bidi_props(c->o, c->par);
#endif
/* For each text node to thorugh all of it's format nodes
@ -4229,6 +4238,20 @@ evas_object_textblock_valign_get(const Evas_Object *obj)
return o->valign;
}
EAPI void
evas_object_textblock_bidi_delimiters_set(Evas_Object *obj, const char *delim)
{
TB_HEAD();
eina_stringshare_replace(&o->bidi_delimiters, delim);
}
EAPI const char *
evas_object_textblock_bidi_delimiters_get(const Evas_Object *obj)
{
TB_HEAD_RETURN(NULL);
return o->bidi_delimiters;
}
EAPI const char *
evas_object_textblock_replace_char_get(Evas_Object *obj)
{

View File

@ -145,6 +145,62 @@ evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Paragraph_Props
return EINA_TRUE;
}
/**
* @internal
* Return a -1 terminated array of the indexes of the delimiters (passed in
* delim) found in the string. This result should be used with par_props_get.
*
* @param str The string to parse
* @param delim a list of delimiters to work with.
* @return returns a -1 terminated array of indexes according to positions of the delimiters found. NULL if there were none.
*/
int *
evas_bidi_segment_idxs_get(const Eina_Unicode *str, const char *delim)
{
Eina_Unicode *udelim;
const Eina_Unicode *str_base = str;
int *ret, *tmp_ret;
int ret_idx = 0, ret_len = 10; /* arbitrary choice */
udelim = eina_unicode_utf8_to_unicode(delim, NULL);
ret = malloc(ret_len * sizeof(int));
for ( ; *str ; str++)
{
const Eina_Unicode *del;
for (del = udelim ; *del ; del++)
{
if (*str == *del)
{
if (ret_idx >= ret_len)
{
/* arbitrary choice */
ret_len += 20;
tmp_ret = realloc(ret, ret_len * sizeof(int));
if (!tmp_ret)
{
free(ret);
return NULL;
}
}
ret[ret_idx++] = str - str_base;
break;
}
}
}
free(udelim);
/* If no indexes were found return NULL */
if (ret_idx == 0)
{
free(ret);
return NULL;
}
ret[ret_idx] = -1;
tmp_ret = realloc(ret, (ret_idx + 1) * sizeof(int));
return (tmp_ret) ? tmp_ret : ret;
}
/**
* @internal
* Allocates bidi properties according to ustr. First checks to see if the
@ -159,7 +215,6 @@ evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Paragraph_Props
* @param segment_idxs A -1 terminated array of points to start a new bidi analysis at (used for section high level bidi overrides). - NULL means none.
* @return returns allocated paragraph props on success, NULL otherwise.
*/
Evas_BiDi_Paragraph_Props *
evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len,
int *segment_idxs)

View File

@ -143,6 +143,9 @@ evas_bidi_paragraph_props_unref(Evas_BiDi_Paragraph_Props *bidi_props) EINA_ARG_
Evas_BiDi_Paragraph_Props *
evas_bidi_paragraph_props_new(void) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
int *
evas_bidi_segment_idxs_get(const Eina_Unicode *str, const char *delim) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
#endif
/**
* @}