forked from enlightenment/efl
Evas font-engine: Use binary search for finding index in text props.
I finally got around to verifying it and the list is assured to be monotonic (direction depends on bidi direction). SVN revision: 59903
This commit is contained in:
parent
1b7ff0248e
commit
85cf792f24
|
@ -65,29 +65,81 @@ evas_common_text_props_content_unref(Evas_Text_Props *props)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI Eina_Bool
|
/* Returns the index of the logical char in the props. */
|
||||||
evas_common_text_props_can_split(Evas_Text_Props *props, int _cutoff)
|
EAPI int
|
||||||
|
evas_common_text_props_index_find(Evas_Text_Props *props, int _cutoff)
|
||||||
{
|
{
|
||||||
#ifdef OT_SUPPORT
|
#ifdef OT_SUPPORT
|
||||||
Evas_Font_OT_Info *itr;
|
Evas_Font_OT_Info *ot_info;
|
||||||
size_t i;
|
int min = 0;
|
||||||
itr = props->info->ot + props->start;
|
int max = props->len - 1;
|
||||||
|
int mid;
|
||||||
|
|
||||||
_cutoff += props->text_offset;
|
_cutoff += props->text_offset;
|
||||||
/* FIXME: can I binary search? I don't think this is always sorted */
|
ot_info = props->info->ot + props->start;
|
||||||
for (i = 0 ; i < props->len ; i++, itr++)
|
if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
|
||||||
{
|
{
|
||||||
if (itr->source_cluster == (size_t) _cutoff)
|
/* Monotonic in a descending order */
|
||||||
|
do
|
||||||
{
|
{
|
||||||
return EINA_TRUE;
|
mid = (min + max) / 2;
|
||||||
|
|
||||||
|
if (_cutoff > (int) ot_info[mid].source_cluster)
|
||||||
|
max = mid - 1;
|
||||||
|
else if (_cutoff < (int) ot_info[mid].source_cluster)
|
||||||
|
min = mid + 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
while (min <= max);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Monotonic in an ascending order */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mid = (min + max) / 2;
|
||||||
|
|
||||||
|
if (_cutoff < (int) ot_info[mid].source_cluster)
|
||||||
|
max = mid - 1;
|
||||||
|
else if (_cutoff > (int) ot_info[mid].source_cluster)
|
||||||
|
min = mid + 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (min <= max);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We didn't find the cutoff position. */
|
/* If we didn't find, abort */
|
||||||
ERR("Couldn't find the cutoff position. Is it inside a cluster?");
|
if (min > max)
|
||||||
return EINA_FALSE;
|
return -1;
|
||||||
|
|
||||||
|
ot_info += mid;
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
if (ot_info->source_cluster != (size_t) _cutoff)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mid = props->len - mid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Walk to the last one of the same cluster */
|
||||||
|
for ( ; mid >= 0 ; mid--, ot_info--)
|
||||||
|
{
|
||||||
|
if (ot_info->source_cluster != (size_t) _cutoff)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mid;
|
||||||
#else
|
#else
|
||||||
return EINA_TRUE;
|
return _cutoff;
|
||||||
props = 0; _cutoff = 0;
|
(void) props;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,41 +154,15 @@ evas_common_text_props_split(Evas_Text_Props *base,
|
||||||
|
|
||||||
/* Translate text cutoff pos to string object cutoff point */
|
/* Translate text cutoff pos to string object cutoff point */
|
||||||
#ifdef OT_SUPPORT
|
#ifdef OT_SUPPORT
|
||||||
cutoff = 0;
|
_cutoff = evas_common_text_props_index_find(base, _cutoff);
|
||||||
|
|
||||||
|
if (_cutoff > 0)
|
||||||
{
|
{
|
||||||
Evas_Font_OT_Info *itr;
|
cutoff = (size_t) _cutoff;
|
||||||
size_t i;
|
|
||||||
itr = base->info->ot + base->start;
|
|
||||||
_cutoff += base->text_offset;
|
|
||||||
/* Must do a linear search because this is not always sorted. */
|
|
||||||
for (i = 0 ; i < base->len ; i++, itr++)
|
|
||||||
{
|
|
||||||
if (itr->source_cluster == (size_t) _cutoff)
|
|
||||||
{
|
|
||||||
if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
|
|
||||||
{
|
|
||||||
/* Walk to the last one of the same cluster */
|
|
||||||
for ( ; i < base->len ; i++, itr++)
|
|
||||||
{
|
|
||||||
if (itr->source_cluster != (size_t) _cutoff)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cutoff = base->len - i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cutoff = i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* If we didn't find a reasonable cut location, return. */
|
|
||||||
if (cutoff == 0)
|
|
||||||
{
|
{
|
||||||
ERR("Couldn't find the cutoff position (%d). Is it inside a cluster?", _cutoff);
|
ERR("Couldn't find the cutoff position. Is it inside a cluster?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -71,8 +71,8 @@ evas_common_text_props_content_ref(Evas_Text_Props *props);
|
||||||
void
|
void
|
||||||
evas_common_text_props_content_unref(Evas_Text_Props *props);
|
evas_common_text_props_content_unref(Evas_Text_Props *props);
|
||||||
|
|
||||||
EAPI Eina_Bool
|
EAPI int
|
||||||
evas_common_text_props_can_split(Evas_Text_Props *props, int _cutoff);
|
evas_common_text_props_index_find(Evas_Text_Props *props, int _cutoff);
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext,
|
evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext,
|
||||||
|
|
Loading…
Reference in New Issue