forked from enlightenment/efl
Evas: Changing the font engine to work with Eina_Unicode instead of utf8.
Changing textblock and text objects to work with Eina_Unicode instead of utf8 (internally, API remains intact). Started relying on new fribidi 0.19.2 instead of the old fribidi. A lot of fixes to the font engine. Renaming of evas_common_font_utf8_* to evas_common_encoding_utf8_* This relies on new Eina changes and types: Eina_Unicode, Eina_UStrbuf and Eina_UStringshare. SVN revision: 50595
This commit is contained in:
parent
1a0f8b1c51
commit
a6d428334f
|
@ -280,7 +280,7 @@ AC_ARG_ENABLE([fribidi],
|
|||
|
||||
if test "x${want_fribidi}" = "xyes" -o "x${want_fribidi}" = "xauto" ; then
|
||||
PKG_CHECK_MODULES([FRIBIDI],
|
||||
[fribidi],
|
||||
[fribidi >= 0.19.2],
|
||||
[
|
||||
have_fribidi="yes"
|
||||
AC_DEFINE(HAVE_FRIBIDI, 1, [have fribidi support])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_common.h" /* Includes evas_bidi_utils stuff. */
|
||||
#include "evas_private.h"
|
||||
|
||||
/* save typing */
|
||||
|
@ -16,15 +16,17 @@ struct _Evas_Object_Text
|
|||
DATA32 magic;
|
||||
|
||||
struct {
|
||||
const char *text;
|
||||
const char *font;
|
||||
const char *source;
|
||||
Evas_Font_Size size;
|
||||
const Eina_Unicode *text; /*The shaped text */
|
||||
const char *utf8_text; /* The text exposed to the API */
|
||||
const char *font;
|
||||
const char *source;
|
||||
Evas_Font_Size size;
|
||||
struct {
|
||||
unsigned char r, g, b, a;
|
||||
} outline, shadow, glow, glow2;
|
||||
|
||||
unsigned char style;
|
||||
Evas_BiDi_Props intl_props;
|
||||
} cur, prev;
|
||||
|
||||
float ascent, descent;
|
||||
|
@ -227,8 +229,11 @@ evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size siz
|
|||
{
|
||||
int w, h;
|
||||
|
||||
ENFN->font_string_size_get(ENDT, o->engine_data, o->cur.text, &w, &h);
|
||||
o->ascent = ENFN->font_ascent_get(ENDT, o->engine_data);
|
||||
o->ascent = ENFN->font_ascent_get(ENDT, o->engine_data);
|
||||
ENFN->font_string_size_get(ENDT,
|
||||
o->engine_data,
|
||||
o->cur.text, &o->cur.intl_props,
|
||||
&w, &h); o->ascent = ENFN->font_ascent_get(ENDT, o->engine_data);
|
||||
o->descent = ENFN->font_descent_get(ENDT, o->engine_data);
|
||||
o->max_ascent = ENFN->font_max_ascent_get(ENDT, o->engine_data);
|
||||
o->max_descent = ENFN->font_max_descent_get(ENDT, o->engine_data);
|
||||
|
@ -316,12 +321,12 @@ evas_object_text_font_get(const Evas_Object *obj, const char **font, Evas_Font_S
|
|||
* @param text Text to display.
|
||||
*/
|
||||
EAPI void
|
||||
evas_object_text_text_set(Evas_Object *obj, const char *text)
|
||||
evas_object_text_text_set(Evas_Object *obj, const char *_text)
|
||||
{
|
||||
Evas_Object_Text *o;
|
||||
int is, was;
|
||||
|
||||
if (!text) text = "";
|
||||
Eina_Unicode *text;
|
||||
|
||||
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
||||
return;
|
||||
MAGIC_CHECK_END();
|
||||
|
@ -329,24 +334,48 @@ evas_object_text_text_set(Evas_Object *obj, const char *text)
|
|||
MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
|
||||
return;
|
||||
MAGIC_CHECK_END();
|
||||
if ((o->cur.text) && (text) && (!strcmp(o->cur.text, text))) return;
|
||||
|
||||
text = evas_common_encoding_utf8_to_unicode(_text, NULL);
|
||||
|
||||
if (!text) text = eina_unicode_strdup(EINA_UNICODE_EMPTY_STRING);
|
||||
if ((o->cur.text) && (text) && (!eina_unicode_strcmp(o->cur.text, text)))
|
||||
{
|
||||
free(text);
|
||||
return;
|
||||
}
|
||||
was = evas_object_is_in_output_rect(obj,
|
||||
obj->layer->evas->pointer.x,
|
||||
obj->layer->evas->pointer.y, 1, 1);
|
||||
/* DO II */
|
||||
/*
|
||||
if (o->cur.text) eina_stringshare_del(o->cur.text);
|
||||
if ((text) && (*text)) o->cur.text = eina_stringshare_add(text);
|
||||
else o->cur.text = NULL;
|
||||
*/
|
||||
eina_stringshare_replace(&o->cur.text, text);
|
||||
/*Update intl_props*/
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_update_props(text, &o->cur.intl_props);
|
||||
#endif
|
||||
if (o->cur.text) eina_ustringshare_del(o->cur.text);
|
||||
if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
|
||||
|
||||
if ((text) && (*text))
|
||||
{
|
||||
o->cur.text = eina_ustringshare_add(text);
|
||||
o->cur.utf8_text = eina_stringshare_add(_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
o->cur.text = NULL;
|
||||
o->cur.utf8_text = NULL;
|
||||
}
|
||||
|
||||
o->prev.text = NULL;
|
||||
|
||||
if ((o->engine_data) && (o->cur.text))
|
||||
{
|
||||
int w, h;
|
||||
int l = 0, r = 0, t = 0, b = 0;
|
||||
|
||||
ENFN->font_string_size_get(ENDT, o->engine_data, o->cur.text, &w, &h);
|
||||
ENFN->font_string_size_get(ENDT,
|
||||
o->engine_data,
|
||||
o->cur.text, &o->cur.intl_props,
|
||||
&w, &h);
|
||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
||||
obj->cur.geometry.w = w + l + r;
|
||||
obj->cur.geometry.h = h + t + b;
|
||||
|
@ -375,6 +404,7 @@ evas_object_text_text_set(Evas_Object *obj, const char *text)
|
|||
obj->layer->evas->last_timestamp,
|
||||
NULL);
|
||||
evas_object_inform_call_resize(obj);
|
||||
if (text) free(text);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -394,7 +424,7 @@ evas_object_text_text_get(const Evas_Object *obj)
|
|||
MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
|
||||
return NULL;
|
||||
MAGIC_CHECK_END();
|
||||
return o->cur.text;
|
||||
return o->cur.utf8_text;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -524,7 +554,7 @@ evas_object_text_horiz_advance_get(const Evas_Object *obj)
|
|||
MAGIC_CHECK_END();
|
||||
if (!o->engine_data) return 0;
|
||||
if (!o->cur.text) return 0;
|
||||
return ENFN->font_h_advance_get(ENDT, o->engine_data, o->cur.text);
|
||||
return ENFN->font_h_advance_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -547,7 +577,7 @@ evas_object_text_vert_advance_get(const Evas_Object *obj)
|
|||
MAGIC_CHECK_END();
|
||||
if (!o->engine_data) return 0;
|
||||
if (!o->cur.text) return o->ascent + o->descent;
|
||||
return ENFN->font_v_advance_get(ENDT, o->engine_data, o->cur.text);
|
||||
return ENFN->font_v_advance_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -587,7 +617,7 @@ evas_object_text_char_pos_get(const Evas_Object *obj, int pos, Evas_Coord *cx, E
|
|||
if (!o->cur.text) return EINA_FALSE;
|
||||
inset =
|
||||
ENFN->font_inset_get(ENDT, o->engine_data, o->cur.text);
|
||||
ret = ENFN->font_char_coords_get(ENDT, o->engine_data, o->cur.text,
|
||||
ret = ENFN->font_char_coords_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props,
|
||||
pos, &x, &y, &w, &h);
|
||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
||||
y += o->max_ascent - t;
|
||||
|
@ -640,8 +670,11 @@ evas_object_text_last_up_to_pos(const Evas_Object *obj, Evas_Coord x, Evas_Coord
|
|||
if (!o->cur.text) return -1;
|
||||
inset =
|
||||
ENFN->font_inset_get(ENDT, o->engine_data, o->cur.text);
|
||||
return ENFN->font_last_up_to_pos(ENDT, o->engine_data, o->cur.text,
|
||||
x + inset, y - o->max_ascent);
|
||||
return ENFN->font_last_up_to_pos(ENDT,
|
||||
o->engine_data,
|
||||
o->cur.text, &o->cur.intl_props,
|
||||
x + inset,
|
||||
y - o->max_ascent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -669,9 +702,13 @@ evas_object_text_char_coords_get(const Evas_Object *obj, Evas_Coord x, Evas_Coor
|
|||
if (!o->cur.text) return -1;
|
||||
inset =
|
||||
ENFN->font_inset_get(ENDT, o->engine_data, o->cur.text);
|
||||
ret = ENFN->font_char_at_coords_get(ENDT, o->engine_data, o->cur.text,
|
||||
x + inset, y - o->max_ascent,
|
||||
&rx, &ry, &rw, &rh);
|
||||
ret = ENFN->font_char_at_coords_get(ENDT,
|
||||
o->engine_data,
|
||||
o->cur.text, &o->cur.intl_props,
|
||||
x + inset,
|
||||
y - o->max_ascent,
|
||||
&rx, &ry,
|
||||
&rw, &rh);
|
||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
||||
ry += o->max_ascent - t;
|
||||
rx -= inset + l;
|
||||
|
@ -1258,7 +1295,7 @@ evas_string_char_next_get(const char *str, int pos, int *decoded)
|
|||
if (decoded) *decoded = 0;
|
||||
if ((!str) || (pos < 0)) return 0;
|
||||
p = pos;
|
||||
d = evas_common_font_utf8_get_next((unsigned char *)str, &p);
|
||||
d = evas_common_encoding_utf8_get_next((unsigned char *)str, &p);
|
||||
if (decoded) *decoded = d;
|
||||
return p;
|
||||
}
|
||||
|
@ -1278,7 +1315,7 @@ evas_string_char_prev_get(const char *str, int pos, int *decoded)
|
|||
if (decoded) *decoded = 0;
|
||||
if ((!str) || (pos < 1)) return 0;
|
||||
p = pos;
|
||||
d = evas_common_font_utf8_get_prev((unsigned char *)str, &p);
|
||||
d = evas_common_encoding_utf8_get_prev((unsigned char *)str, &p);
|
||||
if (decoded) *decoded = d;
|
||||
return p;
|
||||
}
|
||||
|
@ -1293,7 +1330,7 @@ EAPI int
|
|||
evas_string_char_len_get(const char *str)
|
||||
{
|
||||
if (!str) return 0;
|
||||
return evas_common_font_utf8_get_len((const unsigned char *) str);
|
||||
return evas_common_encoding_utf8_get_len((const unsigned char *) str);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1417,6 +1454,9 @@ evas_object_text_new(void)
|
|||
o = calloc(1, sizeof(Evas_Object_Text));
|
||||
o->magic = MAGIC_OBJ_TEXT;
|
||||
o->prev = o->cur;
|
||||
#ifdef BIDI_SUPPORT
|
||||
o->cur.intl_props.direction = FRIBIDI_PAR_ON;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -1431,10 +1471,13 @@ evas_object_text_free(Evas_Object *obj)
|
|||
return;
|
||||
MAGIC_CHECK_END();
|
||||
/* free obj */
|
||||
if (o->cur.text) eina_stringshare_del(o->cur.text);
|
||||
if (o->cur.text) eina_ustringshare_del(o->cur.text);
|
||||
if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
|
||||
if (o->cur.font) eina_stringshare_del(o->cur.font);
|
||||
if (o->cur.source) eina_stringshare_del(o->cur.source);
|
||||
if (o->engine_data) evas_font_free(obj->layer->evas, o->engine_data);
|
||||
if (o->cur.intl_props.embedding_levels) free(o->cur.intl_props.embedding_levels);
|
||||
if (o->cur.intl_props.char_types) free(o->cur.intl_props.char_types);
|
||||
o->magic = 0;
|
||||
free(o);
|
||||
}
|
||||
|
@ -1520,7 +1563,7 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur
|
|||
obj->cur.geometry.h, \
|
||||
obj->cur.geometry.w, \
|
||||
obj->cur.geometry.h, \
|
||||
o->cur.text);
|
||||
o->cur.text, &o->cur.intl_props);
|
||||
#if 0
|
||||
#define DRAW_TEXT(ox, oy) \
|
||||
if ((o->engine_data) && (o->cur.text)) \
|
||||
|
@ -1537,7 +1580,7 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur
|
|||
obj->cur.cache.geometry.h, \
|
||||
obj->cur.geometry.w, \
|
||||
obj->cur.geometry.h, \
|
||||
o->cur.text);
|
||||
o->cur.text, &o->cur.intl_props);
|
||||
#endif
|
||||
/* shadows */
|
||||
if (o->cur.style == EVAS_TEXT_STYLE_SHADOW)
|
||||
|
@ -1724,8 +1767,8 @@ evas_object_text_render_pre(Evas_Object *obj)
|
|||
(strcmp(o->cur.font, o->prev.font))) ||
|
||||
((o->cur.font) && (!o->prev.font)) ||
|
||||
((!o->cur.font) && (o->prev.font)) ||
|
||||
((o->cur.text) && (o->prev.text) &&
|
||||
(strcmp(o->cur.text, o->prev.text))) ||
|
||||
((o->cur.text) && (o->prev.text) &&
|
||||
(eina_unicode_strcmp(o->cur.text, o->prev.text))) ||
|
||||
((o->cur.text) && (!o->prev.text)) ||
|
||||
((!o->cur.text) && (o->prev.text)) ||
|
||||
((o->cur.style != o->prev.style)) ||
|
||||
|
@ -1860,7 +1903,10 @@ _evas_object_text_rehint(Evas_Object *obj)
|
|||
int w, h;
|
||||
int l = 0, r = 0, t = 0, b = 0;
|
||||
|
||||
ENFN->font_string_size_get(ENDT, o->engine_data, o->cur.text, &w, &h);
|
||||
ENFN->font_string_size_get(ENDT,
|
||||
o->engine_data,
|
||||
o->cur.text, &o->cur.intl_props,
|
||||
&w, &h);
|
||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
||||
obj->cur.geometry.w = w + l + r;
|
||||
obj->cur.geometry.h = h + t + b;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,6 +39,7 @@ evas_convert_grypal_6.c \
|
|||
evas_convert_yuv.c \
|
||||
evas_cpu.c \
|
||||
evas_draw_main.c \
|
||||
evas_encoding.c \
|
||||
evas_font_draw.c \
|
||||
evas_font_load.c \
|
||||
evas_font_main.c \
|
||||
|
@ -67,7 +68,7 @@ evas_scale_span.c \
|
|||
evas_tiler.c \
|
||||
evas_regionbuf.c \
|
||||
evas_pipe.c \
|
||||
evas_intl_utils.c \
|
||||
evas_bidi_utils.c \
|
||||
evas_map_image.c \
|
||||
evas_map_image.h
|
||||
|
||||
|
@ -87,6 +88,7 @@ evas_convert_rgb_32.h \
|
|||
evas_convert_rgb_8.h \
|
||||
evas_convert_yuv.h \
|
||||
evas_draw.h \
|
||||
evas_encoding.h \
|
||||
evas_font.h \
|
||||
evas_font_private.h \
|
||||
evas_gradient.h \
|
||||
|
@ -107,7 +109,7 @@ evas_scale_smooth_scaler_noscale.c \
|
|||
evas_scale_smooth_scaler_up.c \
|
||||
evas_scale_span.h \
|
||||
evas_pipe.h \
|
||||
evas_intl_utils.h \
|
||||
evas_bidi_utils.h \
|
||||
evas_map_image_internal.c \
|
||||
evas_map_image_core.c \
|
||||
evas_map_image_loop.c
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "evas_common.h"
|
||||
#include "evas_bidi_utils.h"
|
||||
#include "evas_encoding.h"
|
||||
|
||||
#include "evas_font_private.h"
|
||||
|
||||
#ifdef BIDI_SUPPORT
|
||||
#include <fribidi/fribidi.h>
|
||||
|
||||
#define _SAFE_FREE(x) \
|
||||
do { \
|
||||
if (x) \
|
||||
{ \
|
||||
free(x); \
|
||||
x = NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
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))
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
}
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
evas_bidi_update_props(Eina_Unicode *ustr, Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
EvasBiDiCharType *char_types = NULL;
|
||||
EvasBiDiLevel *embedding_levels = NULL;
|
||||
EvasBiDiJoiningType *join_types = NULL;
|
||||
size_t len;
|
||||
|
||||
if (!ustr)
|
||||
return -2;
|
||||
|
||||
if (!evas_bidi_is_rtl_str(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)
|
||||
{
|
||||
len = -2;
|
||||
goto cleanup;
|
||||
}
|
||||
fribidi_get_bidi_types(ustr, len, char_types);
|
||||
|
||||
embedding_levels = (EvasBiDiLevel *)malloc(sizeof(EvasBiDiLevel) * len);
|
||||
if (!embedding_levels)
|
||||
{
|
||||
len = -2;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!fribidi_get_par_embedding_levels(char_types, len, &intl_props->direction, embedding_levels))
|
||||
{
|
||||
len = -2;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
join_types = (EvasBiDiJoiningType *) malloc(sizeof(EvasBiDiJoiningType) * len);
|
||||
if (!join_types)
|
||||
{
|
||||
len = -2;
|
||||
goto cleanup;
|
||||
}
|
||||
fribidi_get_joining_types(ustr, len, join_types);
|
||||
|
||||
fribidi_join_arabic(char_types, len, embedding_levels, join_types);
|
||||
|
||||
|
||||
/* Actually modify the string */
|
||||
fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC, embedding_levels, len, join_types,
|
||||
ustr);
|
||||
|
||||
/* clean up */
|
||||
if (intl_props->embedding_levels)
|
||||
{
|
||||
free(intl_props->embedding_levels);
|
||||
}
|
||||
intl_props->embedding_levels = embedding_levels;
|
||||
|
||||
/* clean up */
|
||||
|
||||
if (intl_props->char_types)
|
||||
{
|
||||
free(intl_props->char_types);
|
||||
}
|
||||
intl_props->char_types = char_types;
|
||||
|
||||
|
||||
if (join_types) free(join_types);
|
||||
|
||||
return len;
|
||||
|
||||
/* Cleanup */
|
||||
cleanup:
|
||||
if (join_types) free(join_types);
|
||||
if (char_types) free(char_types);
|
||||
if (embedding_levels) free(embedding_levels);
|
||||
evas_bidi_props_clean(intl_props); /*Mark that we don't need bidi handling */
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
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))
|
||||
return 0;
|
||||
|
||||
len = eina_unicode_strlen(ustr);
|
||||
|
||||
if (_v_to_l) {
|
||||
int i;
|
||||
v_to_l = *_v_to_l = calloc(len, sizeof(EvasBiDiStrIndex));
|
||||
if (!v_to_l)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
/* init the array for fribidi */
|
||||
for (i = 0 ; i < len ; i++)
|
||||
{
|
||||
v_to_l[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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->char_types,
|
||||
len, 0, intl_props->direction,
|
||||
intl_props->embedding_levels, ustr, v_to_l))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
/* ERROR HANDLING */
|
||||
error:
|
||||
_SAFE_FREE(v_to_l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
EvasBiDiStrIndex
|
||||
evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDiStrIndex position)
|
||||
{
|
||||
int i;
|
||||
EvasBiDiStrIndex *ind;
|
||||
if (position >= len || !v_to_l)
|
||||
return position;
|
||||
|
||||
for (i = 0, ind = v_to_l ; i < len ; i++, ind++)
|
||||
{
|
||||
if (*ind == position)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
evas_bidi_is_rtl_char(EvasBiDiLevel *embedded_level_list, EvasBiDiStrIndex index)
|
||||
{
|
||||
if(!embedded_level_list || index < 0)
|
||||
return EINA_FALSE;
|
||||
return (FRIBIDI_IS_RTL(embedded_level_list[index])) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
evas_bidi_props_clean(Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
_SAFE_FREE(intl_props->embedding_levels);
|
||||
_SAFE_FREE(intl_props->char_types);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
#ifndef _EVAS_BIDI_UTILS
|
||||
#define _EVAS_BIDI_UTILS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FRIBIDI
|
||||
# define USE_FRIBIDI
|
||||
# define BIDI_SUPPORT
|
||||
#endif
|
||||
|
||||
#include "evas_common.h"
|
||||
|
||||
#ifdef USE_FRIBIDI
|
||||
# include <fribidi/fribidi.h>
|
||||
#endif
|
||||
|
||||
/* abstract fribidi - we statically define sizes here because otherwise we would
|
||||
* have to ifdef everywhere (because function decorations may change with/without
|
||||
* bidi support)
|
||||
* These types should only be passed as pointers! i.e do not directely use any of
|
||||
* these types in function declarations. Defining as void should help ensuring that.
|
||||
*/
|
||||
|
||||
#ifdef USE_FRIBIDI
|
||||
# define _EVAS_BIDI_TYPEDEF(type) \
|
||||
typedef FriBidi ## type EvasBiDi ## type
|
||||
#else
|
||||
# define _EVAS_BIDI_TYPEDEF(type) \
|
||||
typedef void EvasBiDi ## type
|
||||
#endif
|
||||
|
||||
#if 0 /* We are using Eina_Unicode instead */
|
||||
_EVAS_BIDI_TYPEDEF(Char);
|
||||
#endif
|
||||
_EVAS_BIDI_TYPEDEF(CharType);
|
||||
_EVAS_BIDI_TYPEDEF(ParType);
|
||||
_EVAS_BIDI_TYPEDEF(StrIndex);
|
||||
_EVAS_BIDI_TYPEDEF(Level);
|
||||
_EVAS_BIDI_TYPEDEF(JoiningType);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
struct _Evas_BiDi_Props {
|
||||
EvasBiDiCharType *char_types; /* BiDi char types */
|
||||
EvasBiDiLevel *embedding_levels; /* BiDi embedding levels */
|
||||
#ifdef USE_FRIBIDI
|
||||
EvasBiDiParType direction; /* The paragraph direction, FIXME-tom: should be a
|
||||
pointer to the paragraph structure */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _Evas_BiDi_Props Evas_BiDi_Props;
|
||||
|
||||
|
||||
#ifdef USE_FRIBIDI
|
||||
|
||||
# define EVAS_BIDI_IS_BIDI_PROP(intl_props) ((intl_props) && (intl_props)->char_types)
|
||||
# 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
|
||||
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(Eina_Unicode *text, Evas_BiDi_Props *intl_props) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/* 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);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,211 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_encoding.h"
|
||||
|
||||
EAPI int
|
||||
evas_common_encoding_utf8_get_next(const unsigned char *buf, int *iindex)
|
||||
{
|
||||
/* Reads UTF8 bytes from @buf, starting at *@index and returns
|
||||
* the decoded code point at iindex offset, and advances iindex
|
||||
* to the next code point after this.
|
||||
*
|
||||
* Returns 0 to indicate there is no next char
|
||||
*/
|
||||
int index = *iindex, len, r;
|
||||
unsigned char d, d2, d3, d4;
|
||||
|
||||
/* if this char is the null terminator, exit */
|
||||
if (!buf[index])
|
||||
return 0;
|
||||
|
||||
d = buf[index++];
|
||||
|
||||
while (buf[index] && ((buf[index] & 0xc0) == 0x80))
|
||||
index++;
|
||||
len = index - *iindex;
|
||||
|
||||
if (len == 1)
|
||||
r = d;
|
||||
else if (len == 2)
|
||||
{
|
||||
/* 2 bytes */
|
||||
d2 = buf[*iindex + 1];
|
||||
r = d & 0x1f; /* copy lower 5 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f); /* copy lower 6 */
|
||||
}
|
||||
else if (len == 3)
|
||||
{
|
||||
/* 3 bytes */
|
||||
d2 = buf[*iindex + 1];
|
||||
d3 = buf[*iindex + 2];
|
||||
r = d & 0x0f; /* copy lower 4 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d3 & 0x3f);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 4 bytes */
|
||||
d2 = buf[*iindex + 1];
|
||||
d3 = buf[*iindex + 2];
|
||||
d4 = buf[*iindex + 3];
|
||||
r = d & 0x0f; /* copy lower 4 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d3 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d4 & 0x3f);
|
||||
}
|
||||
|
||||
*iindex = index;
|
||||
return r;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_common_encoding_utf8_get_prev(const unsigned char *buf, int *iindex)
|
||||
{
|
||||
/* Reads UTF8 bytes from @buf, starting at *@index and returns
|
||||
* the decoded code point at iindex offset, and advances iindex
|
||||
* to the prev code point after this.
|
||||
*
|
||||
* Returns 0 to indicate there is no prev char
|
||||
*/
|
||||
|
||||
int r;
|
||||
int index = *iindex;
|
||||
/* although when index == 0 there's no previous char, we still want to get
|
||||
* the current char */
|
||||
if (index < 0)
|
||||
return 0;
|
||||
|
||||
/* First obtain the codepoint at iindex */
|
||||
r = evas_common_encoding_utf8_get_next(buf, &index);
|
||||
|
||||
/* Next advance iindex to previous codepoint */
|
||||
index = *iindex;
|
||||
index--;
|
||||
while ((index > 0) && ((buf[index] & 0xc0) == 0x80))
|
||||
index--;
|
||||
|
||||
*iindex = index;
|
||||
return r;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_common_encoding_utf8_get_last(const unsigned char *buf, int buflen)
|
||||
{
|
||||
/* jumps to the nul byte at the buffer end and decodes backwards and
|
||||
* returns the offset index byte in the buffer where the last character
|
||||
* in the buffer begins.
|
||||
*
|
||||
* Returns -1 to indicate an error
|
||||
*/
|
||||
int index;
|
||||
unsigned char d;
|
||||
|
||||
if (buflen < 1) return 0;
|
||||
index = buflen - 1;
|
||||
d = buf[index];
|
||||
if (!(d & 0x80))
|
||||
return index;
|
||||
else
|
||||
{
|
||||
while (index > 0)
|
||||
{
|
||||
index--;
|
||||
d = buf[index];
|
||||
if ((d & 0xc0) != 0x80)
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_common_encoding_utf8_get_len(const unsigned char *buf)
|
||||
{
|
||||
/* returns the number of utf8 characters (not bytes) in the string */
|
||||
int index = 0, len = 0;
|
||||
|
||||
while (buf[index])
|
||||
{
|
||||
if ((buf[index] & 0xc0) != 0x80)
|
||||
len++;
|
||||
index++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* FIXME: Should optimize! */
|
||||
EAPI Eina_Unicode *
|
||||
evas_common_encoding_utf8_to_unicode(const unsigned char *utf, int *_len)
|
||||
{
|
||||
int len, i;
|
||||
int index;
|
||||
Eina_Unicode *buf, *ind;
|
||||
|
||||
len = evas_common_encoding_utf8_get_len(utf);
|
||||
if (_len)
|
||||
*_len = len;
|
||||
buf = (Eina_Unicode *) calloc(sizeof(Eina_Unicode), (len + 1));
|
||||
if (!buf) return buf;
|
||||
|
||||
for (i = 0, index = 0, ind = buf ; i < len ; i++, ind++)
|
||||
{
|
||||
*ind = evas_common_encoding_utf8_get_next(utf, &index);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
EAPI char *
|
||||
evas_common_encoding_unicode_to_utf8(const Eina_Unicode *uni, int *_len)
|
||||
{
|
||||
char *buf;
|
||||
const Eina_Unicode *uind;
|
||||
char *ind;
|
||||
int ulen, len;
|
||||
|
||||
ulen = eina_unicode_strlen(uni);
|
||||
buf = (char *) calloc(ulen + 1, EVAS_ENCODING_UTF8_BYTES_PER_CHAR);
|
||||
|
||||
len = 0;
|
||||
for (uind = uni, ind = buf ; *uind ; uind++)
|
||||
{
|
||||
if (*uind <= 0x7F) /* 1 byte char */
|
||||
{
|
||||
*ind++ = *uind;
|
||||
len += 1;
|
||||
}
|
||||
else if (*uind <= 0x7FF) /* 2 byte char */
|
||||
{
|
||||
*ind++ = 0xC0 | (unsigned char) (*uind >> 6);
|
||||
*ind++ = 0x80 | (unsigned char) (*uind & 0x3F);
|
||||
len += 2;
|
||||
}
|
||||
else if (*uind <= 0xFFFF) /* 3 byte char */
|
||||
{
|
||||
*ind++ = 0xE0 | (unsigned char) (*uind >> 12);
|
||||
*ind++ = 0x80 | (unsigned char) ((*uind >> 6) & 0x3F);
|
||||
*ind++ = 0x80 | (unsigned char) (*uind & 0x3F);
|
||||
len += 3;
|
||||
}
|
||||
else /* 4 byte char */
|
||||
{
|
||||
*ind++ = 0xF0 | (unsigned char) ((*uind >> 18) & 0x07);
|
||||
*ind++ = 0x80 | (unsigned char) ((*uind >> 12) & 0x3F);
|
||||
*ind++ = 0x80 | (unsigned char) ((*uind >> 6) & 0x3F);
|
||||
*ind++ = 0x80 | (unsigned char) (*uind & 0x3F);
|
||||
len += 4;
|
||||
}
|
||||
}
|
||||
buf = realloc(buf, len + 1);
|
||||
buf[len] = '\0';
|
||||
if (_len)
|
||||
*_len = len;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef EVAS_ENCODING_H
|
||||
#define EVAS_ENCODING_H
|
||||
#include <Eina.h>
|
||||
|
||||
/* FIXME: An assumption that will probably break in the future */
|
||||
#define EVAS_ENCODING_UTF8_BYTES_PER_CHAR 4
|
||||
|
||||
EAPI int
|
||||
evas_common_encoding_utf8_get_next(const unsigned char *buf, int *iindex);
|
||||
|
||||
EAPI int
|
||||
evas_common_encoding_utf8_get_prev(const unsigned char *buf, int *iindex);
|
||||
|
||||
EAPI int
|
||||
evas_common_encoding_utf8_get_last(const unsigned char *buf, int buflen);
|
||||
|
||||
EAPI int
|
||||
evas_common_encoding_utf8_get_len(const unsigned char *buf);
|
||||
|
||||
EAPI Eina_Unicode *
|
||||
evas_common_encoding_utf8_to_unicode(const unsigned char *utf, int *_len) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
||||
|
||||
EAPI char *
|
||||
evas_common_encoding_unicode_to_utf8(const Eina_Unicode *uni, int *_len) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#ifndef _EVAS_FONT_H
|
||||
#define _EVAS_FONT_H
|
||||
#include "evas_bidi_utils.h"
|
||||
|
||||
|
||||
/* main */
|
||||
|
@ -18,14 +19,14 @@ EAPI int evas_common_font_max_ascent_get (RGBA_Font *fn);
|
|||
EAPI int evas_common_font_max_descent_get (RGBA_Font *fn);
|
||||
EAPI int evas_common_font_get_line_advance (RGBA_Font *fn);
|
||||
|
||||
EAPI int evas_common_font_utf8_get_next (const unsigned char *buf, int *iindex);
|
||||
EAPI int evas_common_font_utf8_get_prev (const unsigned char *buf, int *iindex);
|
||||
EAPI int evas_common_font_utf8_get_last (const unsigned char *buf, int buflen);
|
||||
EAPI int evas_common_font_utf8_get_len (const unsigned char *buf);
|
||||
EINA_DEPRECATED EAPI int evas_common_font_utf8_get_next (const unsigned char *buf, int *iindex);
|
||||
EINA_DEPRECATED EAPI int evas_common_font_utf8_get_prev (const unsigned char *buf, int *iindex);
|
||||
EINA_DEPRECATED EAPI int evas_common_font_utf8_get_last (const unsigned char *buf, int buflen);
|
||||
EINA_DEPRECATED EAPI int evas_common_font_utf8_get_len (const unsigned char *buf);
|
||||
|
||||
/* draw */
|
||||
|
||||
EAPI void evas_common_font_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text);
|
||||
EAPI void evas_common_font_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props);
|
||||
EAPI int evas_common_font_glyph_search (RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl);
|
||||
EAPI RGBA_Font_Glyph *evas_common_font_int_cache_glyph_get (RGBA_Font_Int *fi, FT_UInt index);
|
||||
|
||||
|
@ -62,12 +63,12 @@ EAPI RGBA_Font_Int *evas_common_font_int_find (const char *name,
|
|||
/* query */
|
||||
|
||||
EAPI int evas_common_font_query_kerning (RGBA_Font_Int* fi, FT_UInt prev, FT_UInt index, int* kerning);
|
||||
EAPI void evas_common_font_query_size (RGBA_Font *fn, const char *text, int *w, int *h);
|
||||
EAPI int evas_common_font_query_inset (RGBA_Font *fn, const char *text);
|
||||
EAPI void evas_common_font_query_advance (RGBA_Font *fn, const char *text, int *h_adv, int *v_adv);
|
||||
EAPI int evas_common_font_query_char_coords (RGBA_Font *fn, const char *text, int pos, int *cx, int *cy, int *cw, int *ch);
|
||||
EAPI int evas_common_font_query_text_at_pos (RGBA_Font *fn, const char *text, int x, int y, int *cx, int *cy, int *cw, int *ch);
|
||||
EAPI int evas_common_font_query_last_up_to_pos (RGBA_Font *fn, const char *text, int x, int y);
|
||||
EAPI void evas_common_font_query_size (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h);
|
||||
EAPI int evas_common_font_query_inset (RGBA_Font *fn, const Eina_Unicode *text);
|
||||
EAPI void evas_common_font_query_advance (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *h_adv, int *v_adv);
|
||||
EAPI int evas_common_font_query_char_coords (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch);
|
||||
EAPI int evas_common_font_query_char_at_coords (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch);
|
||||
EAPI int evas_common_font_query_last_up_to_pos (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y);
|
||||
|
||||
void evas_common_font_load_init(void);
|
||||
void evas_common_font_load_shutdown(void);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "evas_private.h"
|
||||
#include "evas_blend_private.h"
|
||||
|
||||
#include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */
|
||||
#include "evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */
|
||||
#include "evas_font_private.h" /* for Frame-Queuing support */
|
||||
|
||||
#define WORD_CACHE_MAXLEN 50
|
||||
|
@ -20,7 +20,7 @@ struct prword {
|
|||
int size;
|
||||
struct cinfo *cinfo;
|
||||
RGBA_Font *font;
|
||||
const char *str;
|
||||
const Eina_Unicode *str;
|
||||
int len;
|
||||
DATA8 *im;
|
||||
int roww;
|
||||
|
@ -34,7 +34,6 @@ struct cinfo {
|
|||
FT_UInt index;
|
||||
struct { int x, y; } pos;
|
||||
int posx;
|
||||
char chr;
|
||||
RGBA_Font_Glyph *fg;
|
||||
struct {
|
||||
int w,h;
|
||||
|
@ -46,7 +45,7 @@ struct cinfo {
|
|||
|
||||
LK(lock_words); // for word cache call
|
||||
static Eina_Inlist *words = NULL;
|
||||
static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const char *text, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning);
|
||||
static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *text, Evas_BiDi_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning);
|
||||
|
||||
EAPI void
|
||||
evas_common_font_draw_init(void)
|
||||
|
@ -390,16 +389,22 @@ evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* BiDi handling: We recieve the shaped string + other props from intl_props,
|
||||
* we need to reorder it so we'll have the visual string (the way we draw)
|
||||
* and then for kerning we have to switch the order of the kerning query (as the prev
|
||||
* is on the right, and not on the left).
|
||||
*/
|
||||
static void
|
||||
evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *in_text,
|
||||
RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w, int ext_h, RGBA_Font_Int *fi,
|
||||
int im_w, int im_h __UNUSED__, int use_kerning
|
||||
evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *in_text,
|
||||
const Evas_BiDi_Props *intl_props, RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w,
|
||||
int ext_h, RGBA_Font_Int *fi, int im_w, int im_h __UNUSED__, int use_kerning
|
||||
)
|
||||
{
|
||||
int pen_x, pen_y;
|
||||
int last_adv;
|
||||
int chr;
|
||||
const char *text = in_text;
|
||||
const Eina_Unicode *text = in_text;
|
||||
int len;
|
||||
FT_Face pface = NULL;
|
||||
FT_UInt prev_index;
|
||||
|
@ -410,14 +415,11 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
|
||||
|
||||
#if defined(METRIC_CACHE) || defined(WORD_CACHE)
|
||||
/* A fast (portable) strNlen would be nice (there is a wcsnlen strangely) */
|
||||
if ((p = memchr(text, 0, WORD_CACHE_MAXLEN)))
|
||||
len = p - text;
|
||||
else
|
||||
len = WORD_CACHE_MAXLEN;
|
||||
/* A fast strNlen would be nice (there is a wcsnlen strangely) */
|
||||
len = evas_common_econding_unicode_strlen(text);
|
||||
|
||||
if (len > 2 && len < WORD_CACHE_MAXLEN){
|
||||
struct prword *word = evas_font_word_prerender(dc, text, len, fn, fi,
|
||||
struct prword *word = evas_font_word_prerender(dc, text, intl_props, len, fn, fi,
|
||||
use_kerning);
|
||||
if (word){
|
||||
int j,rowstart,rowend,xstart,xrun;
|
||||
|
@ -481,35 +483,39 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
/*FIXME: should get the direction by parmater */
|
||||
EvasIntlParType direction = FRIBIDI_TYPE_ON;
|
||||
EvasIntlLevel *level_list;
|
||||
#ifdef BIDI_SUPPORT
|
||||
Eina_Unicode *visual_text;
|
||||
|
||||
/* change the text to visual ordering and update the level list
|
||||
* for as minimum impact on the code as possible just use text as an
|
||||
* holder, will change in the future.*/
|
||||
char *visual_text = evas_intl_utf8_to_visual(in_text, &len, &direction, NULL, NULL, &level_list);
|
||||
text = (visual_text) ? visual_text : in_text;
|
||||
|
||||
visual_text = eina_unicode_strdup(in_text);
|
||||
|
||||
if (visual_text)
|
||||
{
|
||||
evas_bidi_props_reorder_line(visual_text, intl_props, NULL);
|
||||
text = visual_text;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = in_text;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
pen_x = x;
|
||||
pen_y = y;
|
||||
last_adv = 0;
|
||||
prev_index = 0;
|
||||
im = dst->image.data;
|
||||
for (char_index = 0, c = 0, chr = 0; text[chr]; char_index++)
|
||||
for (char_index = 0, c = 0; *text; text++, char_index++)
|
||||
{
|
||||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int chr_x, chr_y;
|
||||
int gl, kern;
|
||||
|
||||
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
gl = *text;
|
||||
|
||||
if (gl == 0) break;
|
||||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
|
@ -521,33 +527,40 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
FTUNLOCK();
|
||||
fi->src->current_size = fi->size;
|
||||
}
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
if (!fg)
|
||||
{
|
||||
LKU(fi->ft_mutex);
|
||||
continue;
|
||||
}
|
||||
/* hmmm kerning means i can't sanely do my own cached metric tables! */
|
||||
/* grrr - this means font face sharing is kinda... not an option if */
|
||||
/* you want performance */
|
||||
if ((use_kerning) && (prev_index) && (index) &&
|
||||
(pface == fi->src->ft.face))
|
||||
{
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
/* if it's rtl, the kerning matching should be reversed, i.e prev
|
||||
* index is now the index and the other way around. */
|
||||
if (evas_intl_is_rtl_char(level_list, char_index))
|
||||
{
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
#ifdef BIDI_SUPPORT
|
||||
/* if it's rtl, the kerning matching should be reversed, i.e prev
|
||||
* index is now the index and the other way around.
|
||||
* There is a slight exception when there are compositing chars
|
||||
* involved.*/
|
||||
if (intl_props &&
|
||||
evas_bidi_is_rtl_char(intl_props->embedding_levels, char_index) &&
|
||||
fg->glyph->advance.x >> 16 > 0)
|
||||
{
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
}
|
||||
|
||||
pface = fi->src->ft.face;
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
LKU(fi->ft_mutex);
|
||||
if (!fg) continue;
|
||||
|
||||
if (dc->font_ext.func.gl_new)
|
||||
{
|
||||
|
@ -555,7 +568,13 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
|
||||
fg->ext_dat_free = dc->font_ext.func.gl_free;
|
||||
}
|
||||
|
||||
/* If the current one is not a compositing char, do the previous advance
|
||||
* and set the current advance as the next advance to do */
|
||||
if (fg->glyph->advance.x >> 16 > 0)
|
||||
{
|
||||
pen_x += last_adv;
|
||||
last_adv = fg->glyph->advance.x >> 16;
|
||||
}
|
||||
chr_x = (pen_x + (fg->glyph_out->left));
|
||||
chr_y = (pen_y + (fg->glyph_out->top));
|
||||
|
||||
|
@ -688,17 +707,18 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
}
|
||||
else
|
||||
break;
|
||||
pen_x += fg->glyph->advance.x >> 16;
|
||||
|
||||
prev_index = index;
|
||||
}
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
if (level_list) free(level_list);
|
||||
#ifdef BIDI_SUPPORT
|
||||
if (visual_text) free(visual_text);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
EAPI void
|
||||
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text)
|
||||
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text,
|
||||
const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
int ext_x, ext_y, ext_w, ext_h;
|
||||
int im_w, im_h;
|
||||
|
@ -749,7 +769,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
|
||||
if (!dc->cutout.rects)
|
||||
{
|
||||
evas_common_font_draw_internal(dst, dc, fn, x, y, text,
|
||||
evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props,
|
||||
func, ext_x, ext_y, ext_w, ext_h, fi,
|
||||
im_w, im_h, use_kerning
|
||||
);
|
||||
|
@ -766,7 +786,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
{
|
||||
r = rects->rects + i;
|
||||
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
|
||||
evas_common_font_draw_internal(dst, dc, fn, x, y, text,
|
||||
evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props,
|
||||
func, r->x, r->y, r->w, r->h, fi,
|
||||
im_w, im_h, use_kerning
|
||||
);
|
||||
|
@ -781,12 +801,12 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* FIXME: Where is it freed at? */
|
||||
struct prword *
|
||||
evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning){
|
||||
evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Evas_BiDi_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning){
|
||||
int pen_x, pen_y;
|
||||
struct cinfo *metrics;
|
||||
const char *text;
|
||||
const Eina_Unicode *text = in_text;
|
||||
int chr;
|
||||
FT_Face pface = NULL;
|
||||
FT_UInt prev_index;
|
||||
|
@ -803,7 +823,7 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
|
|||
LKL(lock_words);
|
||||
EINA_INLIST_FOREACH(words,w){
|
||||
if (w->len == len && w->font == fn && fi->size == w->size &&
|
||||
(w->str == in_text || memcmp(w->str,in_text,len) == 0)){
|
||||
(w->str == in_text || memcmp(w->str, in_text, len * sizeof(Eina_Unicode)) == 0)){
|
||||
words = eina_inlist_promote(words, EINA_INLIST_GET(w));
|
||||
LKU(lock_words);
|
||||
return w;
|
||||
|
@ -811,30 +831,15 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
|
|||
}
|
||||
LKU(lock_words);
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
/*FIXME: should get the direction by parmater */
|
||||
EvasIntlParType direction = FRIBIDI_TYPE_ON;
|
||||
EvasIntlLevel *level_list;
|
||||
|
||||
/* change the text to visual ordering and update the level list
|
||||
* for as minimum impact on the code as possible just use text as an
|
||||
* holder, will change in the future.*/
|
||||
char *visual_text = evas_intl_utf8_to_visual(in_text, &len, &direction, NULL, NULL, &level_list);
|
||||
text = (visual_text) ? visual_text : in_text;
|
||||
#else
|
||||
text = in_text;
|
||||
#endif
|
||||
|
||||
gl = dc->font_ext.func.gl_new ? 1: 0;
|
||||
|
||||
pen_x = pen_y = 0;
|
||||
above = 0; below = 0; baseline = 0; height = 0; descent = 0;
|
||||
metrics = malloc(sizeof(struct cinfo) * len);
|
||||
/* First pass: Work out how big */
|
||||
for (char_index = 0, c = 0, chr = 0 ; text[chr] ; char_index ++){
|
||||
for (char_index = 0, c = 0, chr = 0 ; *text ; text++, char_index ++){
|
||||
struct cinfo *ci = metrics + char_index;
|
||||
ci->chr = text[chr];
|
||||
ci->gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
ci->gl = *text;
|
||||
if (ci->gl == 0) break;
|
||||
ci->index = evas_common_font_glyph_search(fn, &fi, ci->gl);
|
||||
LKL(fi->ft_mutex);
|
||||
|
@ -845,16 +850,39 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
|
|||
FTUNLOCK();
|
||||
fi->src->current_size = fi->size;
|
||||
}
|
||||
if (use_kerning && char_index && (pface == fi->src->ft.face))
|
||||
{
|
||||
int kern;
|
||||
if (evas_common_font_query_kerning(fi, prev_index,ci->index,&kern))
|
||||
ci->pos.x += kern;
|
||||
}
|
||||
pface = fi->src->ft.face;
|
||||
ci->fg = evas_common_font_int_cache_glyph_get(fi, ci->index);
|
||||
LKU(fi->ft_mutex);
|
||||
if (!ci->fg) continue;
|
||||
|
||||
/* hmmm kerning means i can't sanely do my own cached metric tables! */
|
||||
/* grrr - this means font face sharing is kinda... not an option if */
|
||||
/* you want performance */
|
||||
if ((use_kerning) && (prev_index) && (ci->index) &&
|
||||
(pface == fi->src->ft.face))
|
||||
{
|
||||
int kern = 0;
|
||||
#ifdef BIDI_SUPPORT
|
||||
/* if it's rtl, the kerning matching should be reversed, i.e prev
|
||||
* index is now the index and the other way around.
|
||||
* There is a slight exception when there are compositing chars
|
||||
* involved.*/
|
||||
if (intl_props &&
|
||||
evas_bidi_is_rtl_char(intl_props->embedding_levels, char_index) &&
|
||||
ci->fg->glyph->advance.x >> 16 > 0)
|
||||
{
|
||||
if (evas_common_font_query_kerning(fi, ci->index, prev_index, &kern))
|
||||
ci->pos.x += kern;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
if (evas_common_font_query_kerning(fi, prev_index, ci->index, &kern))
|
||||
ci->pos.x += kern;
|
||||
}
|
||||
}
|
||||
|
||||
pface = fi->src->ft.face;
|
||||
if (gl){
|
||||
ci->fg->ext_dat =dc->font_ext.func.gl_new(dc->font_ext.data,ci->fg);
|
||||
ci->fg->ext_dat_free = dc->font_ext.func.gl_free;
|
||||
|
@ -897,7 +925,7 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
|
|||
|
||||
save = malloc(sizeof(struct prword));
|
||||
save->cinfo = metrics;
|
||||
save->str = eina_stringshare_add(in_text);
|
||||
save->str = eina_ustringshare_add(text);
|
||||
save->font = fn;
|
||||
save->size = fi->size;
|
||||
save->len = len;
|
||||
|
@ -914,17 +942,12 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const char *in_text, int len, RG
|
|||
struct prword *last = (struct prword *)(words->last);
|
||||
if (last->im) free(last->im);
|
||||
if (last->cinfo) free(last->cinfo);
|
||||
eina_stringshare_del(last->str);
|
||||
eina_ustringshare_del(last->str);
|
||||
words = eina_inlist_remove(words,EINA_INLIST_GET(last));
|
||||
free(last);
|
||||
}
|
||||
LKU(lock_words);
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
if (level_list) free(level_list);
|
||||
if (visual_text) free(visual_text);
|
||||
#endif
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#include "evas_encoding.h"
|
||||
|
||||
#include "evas_font_private.h"
|
||||
|
||||
FT_Library evas_ft_lib = 0;
|
||||
|
@ -207,139 +209,27 @@ evas_common_font_get_line_advance(RGBA_Font *fn)
|
|||
// return ret;
|
||||
}
|
||||
|
||||
/*DEPRECATED! Should use evas_common_encoding_* instead */
|
||||
EAPI int
|
||||
evas_common_font_utf8_get_next(const unsigned char *buf, int *iindex)
|
||||
{
|
||||
/* Reads UTF8 bytes from @buf, starting at *@index and returns
|
||||
* the decoded code point at iindex offset, and advances iindex
|
||||
* to the next code point after this.
|
||||
*
|
||||
* Returns 0 to indicate there is no next char
|
||||
*/
|
||||
int index = *iindex, len, r;
|
||||
unsigned char d, d2, d3, d4;
|
||||
|
||||
/* if this char is the null terminator, exit */
|
||||
if (!buf[index])
|
||||
return 0;
|
||||
|
||||
d = buf[index++];
|
||||
|
||||
while (buf[index] && ((buf[index] & 0xc0) == 0x80))
|
||||
index++;
|
||||
len = index - *iindex;
|
||||
|
||||
if (len == 1)
|
||||
r = d;
|
||||
else if (len == 2)
|
||||
{
|
||||
/* 2 bytes */
|
||||
d2 = buf[*iindex + 1];
|
||||
r = d & 0x1f; /* copy lower 5 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f); /* copy lower 6 */
|
||||
}
|
||||
else if (len == 3)
|
||||
{
|
||||
/* 3 bytes */
|
||||
d2 = buf[*iindex + 1];
|
||||
d3 = buf[*iindex + 2];
|
||||
r = d & 0x0f; /* copy lower 4 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d3 & 0x3f);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 4 bytes */
|
||||
d2 = buf[*iindex + 1];
|
||||
d3 = buf[*iindex + 2];
|
||||
d4 = buf[*iindex + 3];
|
||||
r = d & 0x0f; /* copy lower 4 */
|
||||
r <<= 6;
|
||||
r |= (d2 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d3 & 0x3f);
|
||||
r <<= 6;
|
||||
r |= (d4 & 0x3f);
|
||||
}
|
||||
|
||||
*iindex = index;
|
||||
return r;
|
||||
return evas_common_encoding_utf8_get_next(buf, iindex);
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_common_font_utf8_get_prev(const unsigned char *buf, int *iindex)
|
||||
{
|
||||
/* Reads UTF8 bytes from @buf, starting at *@index and returns
|
||||
* the decoded code point at iindex offset, and advances iindex
|
||||
* to the prev code point after this.
|
||||
*
|
||||
* Returns 0 to indicate there is no prev char
|
||||
*/
|
||||
|
||||
int r;
|
||||
int index = *iindex;
|
||||
/* although when index == 0 there's no previous char, we still want to get
|
||||
* the current char */
|
||||
if (index < 0)
|
||||
return 0;
|
||||
|
||||
/* First obtain the codepoint at iindex */
|
||||
r = evas_common_font_utf8_get_next(buf, &index);
|
||||
|
||||
/* Next advance iindex to previous codepoint */
|
||||
index = *iindex;
|
||||
index--;
|
||||
while ((index > 0) && ((buf[index] & 0xc0) == 0x80))
|
||||
index--;
|
||||
|
||||
*iindex = index;
|
||||
return r;
|
||||
return evas_common_encoding_utf8_get_prev(buf, iindex);
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_common_font_utf8_get_last(const unsigned char *buf, int buflen)
|
||||
{
|
||||
/* jumps to the nul byte at the buffer end and decodes backwards and
|
||||
* returns the offset index byte in the buffer where the last character
|
||||
* in the buffer begins.
|
||||
*
|
||||
* Returns -1 to indicate an error
|
||||
*/
|
||||
int index;
|
||||
unsigned char d;
|
||||
|
||||
if (buflen < 1) return 0;
|
||||
index = buflen - 1;
|
||||
d = buf[index];
|
||||
if (!(d & 0x80))
|
||||
return index;
|
||||
else
|
||||
{
|
||||
while (index > 0)
|
||||
{
|
||||
index--;
|
||||
d = buf[index];
|
||||
if ((d & 0xc0) != 0x80)
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return evas_common_encoding_utf8_get_last(buf, buflen);
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_common_font_utf8_get_len(const unsigned char *buf)
|
||||
{
|
||||
/* returns the number of utf8 characters (not bytes) in the string */
|
||||
int index = 0, len = 0;
|
||||
|
||||
while (buf[index])
|
||||
{
|
||||
if ((buf[index] & 0xc0) != 0x80)
|
||||
len++;
|
||||
index++;
|
||||
}
|
||||
return len;
|
||||
return evas_common_encoding_utf8_get_len(buf);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */
|
||||
#include "evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */
|
||||
#include "evas_font_private.h" /* for Frame-Queuing support */
|
||||
|
||||
EAPI int
|
||||
|
@ -56,9 +56,15 @@ evas_common_font_query_kerning(RGBA_Font_Int* fi,
|
|||
return error;
|
||||
}
|
||||
|
||||
/* string extents */
|
||||
/* size of the string (width and height) in pixels
|
||||
* BiDi handling: We recieve the shaped string + other props from intl_props,
|
||||
* We only care about the size, and the size does not depend on the visual order.
|
||||
* As long as we follow the logical string and get kerning data like we should,
|
||||
* we are fine.
|
||||
*/
|
||||
|
||||
EAPI void
|
||||
evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
|
||||
evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
|
@ -78,14 +84,14 @@ evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
|
|||
// evas_common_font_size_use(fn);
|
||||
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
|
||||
prev_index = 0;
|
||||
for (chr = 0; text[chr];)
|
||||
for (chr = 0; *text; text++)
|
||||
{
|
||||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int chr_x, chr_y, advw;
|
||||
int gl, kern;
|
||||
|
||||
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
gl = *text;
|
||||
if (gl == 0) break;
|
||||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
LKL(fi->ft_mutex);
|
||||
|
@ -101,9 +107,9 @@ evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
|
|||
/* you want performance */
|
||||
kern = 0;
|
||||
if ((use_kerning) && (prev_index) && (index) &&
|
||||
(pface == fi->src->ft.face))
|
||||
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
pen_x += kern;
|
||||
(pface == fi->src->ft.face) &&
|
||||
evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
pen_x += kern;
|
||||
|
||||
pface = fi->src->ft.face;
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
|
@ -111,21 +117,28 @@ evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
|
|||
if (!fg) continue;
|
||||
|
||||
if (kern < 0) kern = 0;
|
||||
chr_x = ((pen_x - kern) + (fg->glyph_out->left));
|
||||
chr_y = (pen_y + (fg->glyph_out->top));
|
||||
// chr_w = fg->glyph_out->bitmap.width;
|
||||
chr_w = fg->glyph_out->bitmap.width + kern;
|
||||
{
|
||||
int advw;
|
||||
|
||||
/* We care about advancing the whole string size, and not the actual
|
||||
* paint size of each string, so we only care about advancing correctly
|
||||
* and not the actual glyph width */
|
||||
advw = ((fg->glyph->advance.x + (kern << 16)) >> 16);
|
||||
chr_x = pen_x - kern;
|
||||
chr_y = pen_y;
|
||||
/* If it's not a compositing char, i.e it advances, we should also add
|
||||
* the left/top padding of the glyph. As we don't care about the padding
|
||||
* as the drawing location remains the same.
|
||||
*/
|
||||
if (advw > 0)
|
||||
{
|
||||
chr_x += fg->glyph_out->left;
|
||||
chr_y += fg->glyph_out->top;
|
||||
}
|
||||
|
||||
advw = ((fg->glyph->advance.x + (kern << 16)) >> 16);
|
||||
if (chr_w < advw) chr_w = advw;
|
||||
}
|
||||
|
||||
if ((!prev_index) && (chr_x < 0))
|
||||
start_x = chr_x;
|
||||
if ((chr_x + chr_w) > end_x)
|
||||
end_x = chr_x + chr_w;
|
||||
if ((chr_x + advw) > end_x)
|
||||
end_x = chr_x + advw;
|
||||
|
||||
pen_x += fg->glyph->advance.x >> 16;
|
||||
prev_index = index;
|
||||
|
@ -136,7 +149,7 @@ evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
|
|||
|
||||
/* text x inset */
|
||||
EAPI int
|
||||
evas_common_font_query_inset(RGBA_Font *fn, const char *text)
|
||||
evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text)
|
||||
{
|
||||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
|
@ -147,8 +160,8 @@ evas_common_font_query_inset(RGBA_Font *fn, const char *text)
|
|||
fi = fn->fonts->data;
|
||||
|
||||
chr = 0;
|
||||
if (!text[0]) return 0;
|
||||
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
if (!*text) return 0;
|
||||
gl = *text;
|
||||
if (gl == 0) return 0;
|
||||
// evas_common_font_size_use(fn);
|
||||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
|
@ -180,14 +193,20 @@ evas_common_font_query_inset(RGBA_Font *fn, const char *text)
|
|||
return fg->glyph_out->left;
|
||||
}
|
||||
|
||||
/* h & v advance */
|
||||
/* h & v advance
|
||||
* BiDi handling: We recieve the shaped string + other props from intl_props,
|
||||
* We don't care about the order, as heights will remain the same (we already did
|
||||
* shaping) and as long as we go through the logical string and match the kerning
|
||||
* this way, we are safe.
|
||||
*/
|
||||
|
||||
EAPI void
|
||||
evas_common_font_query_advance(RGBA_Font *fn, const char *text, int *h_adv, int *v_adv)
|
||||
evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *h_adv, int *v_adv)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int start_x;
|
||||
int chr;
|
||||
int char_index;
|
||||
FT_UInt prev_index;
|
||||
RGBA_Font_Int *fi;
|
||||
FT_Face pface = NULL;
|
||||
|
@ -202,14 +221,13 @@ evas_common_font_query_advance(RGBA_Font *fn, const char *text, int *h_adv, int
|
|||
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
|
||||
FTUNLOCK();
|
||||
prev_index = 0;
|
||||
for (chr = 0; text[chr];)
|
||||
for (char_index = 0 ; *text ; text++, char_index++)
|
||||
{
|
||||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl, kern;
|
||||
|
||||
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
gl = *text;
|
||||
if (gl == 0) break;
|
||||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
LKL(fi->ft_mutex);
|
||||
|
@ -220,105 +238,12 @@ evas_common_font_query_advance(RGBA_Font *fn, const char *text, int *h_adv, int
|
|||
FTUNLOCK();
|
||||
fi->src->current_size = fi->size;
|
||||
}
|
||||
/* hmmm kerning means i can't sanely do my own cached metric tables! */
|
||||
/* grrr - this means font face sharing is kinda... not an option if */
|
||||
/* you want performance */
|
||||
if ((use_kerning) && (prev_index) && (index) &&
|
||||
(pface == fi->src->ft.face))
|
||||
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
pen_x += kern;
|
||||
|
||||
pface = fi->src->ft.face;
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
LKU(fi->ft_mutex);
|
||||
if (!fg) continue;
|
||||
|
||||
chr_x = (pen_x + (fg->glyph_out->left));
|
||||
chr_y = (pen_y + (fg->glyph_out->top));
|
||||
chr_w = fg->glyph_out->bitmap.width;
|
||||
|
||||
pen_x += fg->glyph->advance.x >> 16;
|
||||
prev_index = index;
|
||||
}
|
||||
if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
|
||||
if (h_adv) *h_adv = pen_x - start_x;
|
||||
}
|
||||
|
||||
/* x y w h for char at char pos */
|
||||
EAPI int
|
||||
evas_common_font_query_char_coords(RGBA_Font *fn, const char *in_text, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int prev_chr_end;
|
||||
int chr;
|
||||
int asc, desc;
|
||||
int char_index = 0; /* the index of the current char */
|
||||
int position;
|
||||
const char *text = in_text;
|
||||
int ret_val = 0;
|
||||
FT_UInt prev_index;
|
||||
RGBA_Font_Int *fi;
|
||||
FT_Face pface = NULL;
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
int len = 0;
|
||||
EvasIntlParType direction = FRIBIDI_TYPE_ON;
|
||||
EvasIntlLevel *level_list = NULL;
|
||||
EvasIntlStrIndex *visual_to_logical = NULL;
|
||||
char *visual_text = evas_intl_utf8_to_visual(in_text, &len, &direction, &visual_to_logical, NULL, &level_list);
|
||||
text = (visual_text) ? visual_text : in_text;
|
||||
#endif
|
||||
|
||||
fi = fn->fonts->data;
|
||||
|
||||
pen_x = 0;
|
||||
pen_y = 0;
|
||||
// evas_common_font_size_use(fn);
|
||||
if (fi->src->current_size != fi->size)
|
||||
{
|
||||
FTLOCK();
|
||||
FT_Activate_Size(fi->ft.size);
|
||||
FTUNLOCK();
|
||||
fi->src->current_size = fi->size;
|
||||
}
|
||||
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
|
||||
prev_index = 0;
|
||||
prev_chr_end = 0;
|
||||
asc = evas_common_font_max_ascent_get(fn);
|
||||
desc = evas_common_font_max_descent_get(fn);
|
||||
|
||||
/* find the actual index, not the byte position */
|
||||
for (position = 0 , chr = 0 ; in_text[chr] && chr < pos ; position++) {
|
||||
evas_common_font_utf8_get_next((unsigned char *)in_text, &chr);
|
||||
}
|
||||
/* if we couldn't reach the correct position for some reason,
|
||||
* return with an error */
|
||||
if (chr != pos) {
|
||||
ret_val = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
/* if it's an in string position (not end), get logical position */
|
||||
if (position < len)
|
||||
position = evas_intl_position_visual_to_logical(visual_to_logical, position);
|
||||
#endif
|
||||
|
||||
|
||||
for (char_index = 0, chr = 0; text[chr]; char_index++)
|
||||
{
|
||||
int pchr;
|
||||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl, kern;
|
||||
|
||||
pchr = chr;
|
||||
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
if (gl == 0) break;
|
||||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
LKL(fi->ft_mutex);
|
||||
if (!fg)
|
||||
{
|
||||
LKU(fi->ft_mutex);
|
||||
continue;
|
||||
}
|
||||
// FIXME: Why no FT_Activate_Size here ?
|
||||
kern = 0;
|
||||
/* hmmm kerning means i can't sanely do my own cached metric tables! */
|
||||
|
@ -327,10 +252,14 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const char *in_text, int pos,
|
|||
if ((use_kerning) && (prev_index) && (index) &&
|
||||
(pface == fi->src->ft.face))
|
||||
{
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
#ifdef BIDI_SUPPORT
|
||||
/* if it's rtl, the kerning matching should be reversed, i.e prev
|
||||
* index is now the index and the other way around. */
|
||||
if (evas_intl_is_rtl_char(level_list, char_index))
|
||||
* index is now the index and the other way around.
|
||||
* There is a slight exception when there are compositing chars
|
||||
* involved.*/
|
||||
if (intl_props &&
|
||||
evas_bidi_is_rtl_char(intl_props->embedding_levels, char_index) &&
|
||||
fg->glyph->advance.x >> 16 > 0)
|
||||
{
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
|
@ -345,74 +274,57 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const char *in_text, int pos,
|
|||
}
|
||||
|
||||
pface = fi->src->ft.face;
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
LKU(fi->ft_mutex);
|
||||
if (!fg) continue;
|
||||
|
||||
if (kern < 0) kern = 0;
|
||||
chr_x = ((pen_x - kern) + (fg->glyph_out->left));
|
||||
chr_y = (pen_y + (fg->glyph_out->top));
|
||||
chr_w = fg->glyph_out->bitmap.width + (kern);
|
||||
/* if (text[chr]) */
|
||||
{
|
||||
int advw;
|
||||
|
||||
advw = ((fg->glyph->advance.x + (kern << 16)) >> 16);
|
||||
if (chr_w < advw) chr_w = advw;
|
||||
}
|
||||
if (chr_x > prev_chr_end)
|
||||
{
|
||||
chr_w += (chr_x - prev_chr_end);
|
||||
chr_x = prev_chr_end;
|
||||
}
|
||||
/* we need to see if the char at the visual position is the char wanted */
|
||||
if (char_index == position)
|
||||
{
|
||||
if (cx) *cx = chr_x;
|
||||
if (cy) *cy = -asc;
|
||||
if (cw) *cw = chr_w;
|
||||
if (ch) *ch = asc + desc;
|
||||
ret_val = 1;
|
||||
goto end;
|
||||
}
|
||||
prev_chr_end = chr_x + chr_w;
|
||||
pen_x += fg->glyph->advance.x >> 16;
|
||||
prev_index = index;
|
||||
}
|
||||
end:
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
if (level_list) free(level_list);
|
||||
if (visual_to_logical) free(visual_to_logical);
|
||||
if (visual_text) free(visual_text);
|
||||
#endif
|
||||
|
||||
return ret_val;
|
||||
if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
|
||||
if (h_adv) *h_adv = pen_x - start_x;
|
||||
}
|
||||
|
||||
/* char pos of text at xy pos */
|
||||
/* x y w h for char at char pos
|
||||
* BiDi handling: We recieve the shaped string + other props from intl_props,
|
||||
* We care about the actual drawing location of the string, this is why we need
|
||||
* the visual string. We need to know how it's printed. After that we need to calculate
|
||||
* the reverse kerning in case of rtl parts. "pos" passed to this function is an
|
||||
* index in bytes, that is the actual byte location of the string, we need to find
|
||||
* the index in order to find it in the visual string.
|
||||
*/
|
||||
|
||||
EAPI int
|
||||
evas_common_font_query_text_at_pos(RGBA_Font *fn, const char *in_text, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int prev_chr_end;
|
||||
int chr;
|
||||
int asc, desc;
|
||||
int char_index = 0; /* the index of the current char */
|
||||
const char *text = in_text;
|
||||
int ret_val = -1;
|
||||
int position = 0;
|
||||
const Eina_Unicode *text = in_text;
|
||||
int ret_val = 0;
|
||||
int last_adv;
|
||||
FT_UInt prev_index;
|
||||
RGBA_Font_Int *fi;
|
||||
FT_Face pface = NULL;
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
#ifdef BIDI_SUPPORT
|
||||
int len = 0;
|
||||
EvasIntlParType direction = FRIBIDI_TYPE_ON;
|
||||
EvasIntlLevel *level_list = NULL;
|
||||
EvasIntlStrIndex *visual_to_logical = NULL;
|
||||
char *visual_text = evas_intl_utf8_to_visual(in_text, &len, &direction, NULL, &visual_to_logical, &level_list);
|
||||
text = (visual_text) ? visual_text : in_text;
|
||||
EvasBiDiStrIndex *visual_to_logical = NULL;
|
||||
Eina_Unicode *visual_text;
|
||||
|
||||
visual_text = eina_unicode_strdup(in_text);
|
||||
|
||||
if (visual_text)
|
||||
{
|
||||
evas_bidi_props_reorder_line(visual_text, intl_props, &visual_to_logical);
|
||||
text = visual_text;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = in_text;
|
||||
}
|
||||
len = eina_unicode_strlen(text);
|
||||
#endif
|
||||
|
||||
fi = fn->fonts->data;
|
||||
|
@ -432,20 +344,189 @@ evas_common_font_query_text_at_pos(RGBA_Font *fn, const char *in_text, int x, in
|
|||
prev_chr_end = 0;
|
||||
asc = evas_common_font_max_ascent_get(fn);
|
||||
desc = evas_common_font_max_descent_get(fn);
|
||||
|
||||
for (char_index = 0, chr = 0; text[chr]; char_index++)
|
||||
|
||||
#ifdef BIDI_SUPPORT
|
||||
/* Get the position in the visual string because those are the coords we care about */
|
||||
position = evas_bidi_position_logical_to_visual(visual_to_logical, len, pos);
|
||||
#else
|
||||
position = pos;
|
||||
#endif
|
||||
|
||||
last_adv = 0;
|
||||
for (char_index = 0; *text ; text++, char_index++)
|
||||
{
|
||||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl, kern;
|
||||
|
||||
gl = *text;
|
||||
if (gl == 0) break;
|
||||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
LKL(fi->ft_mutex);
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
if (!fg)
|
||||
{
|
||||
LKU(fi->ft_mutex);
|
||||
continue;
|
||||
}
|
||||
// FIXME: Why no FT_Activate_Size here ?
|
||||
kern = 0;
|
||||
/* hmmm kerning means i can't sanely do my own cached metric tables! */
|
||||
/* grrr - this means font face sharing is kinda... not an option if */
|
||||
/* you want performance */
|
||||
if ((use_kerning) && (prev_index) && (index) &&
|
||||
(pface == fi->src->ft.face))
|
||||
{
|
||||
#ifdef BIDI_SUPPORT
|
||||
/* if it's rtl, the kerning matching should be reversed, i.e prev
|
||||
* index is now the index and the other way around.
|
||||
* There is a slight exception when there are compositing chars
|
||||
* involved.*/
|
||||
if (intl_props &&
|
||||
evas_bidi_is_rtl_char(intl_props->embedding_levels, char_index) &&
|
||||
fg->glyph->advance.x >> 16 > 0)
|
||||
{
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
}
|
||||
|
||||
pface = fi->src->ft.face;
|
||||
LKU(fi->ft_mutex);
|
||||
/* If the current one is not a compositing char, do the previous advance
|
||||
* and set the current advance as the next advance to do */
|
||||
if (fg->glyph->advance.x >> 16 > 0)
|
||||
{
|
||||
pen_x += last_adv;
|
||||
last_adv = fg->glyph->advance.x >> 16;
|
||||
}
|
||||
if (kern < 0) kern = 0;
|
||||
chr_x = ((pen_x - kern) + (fg->glyph_out->left));
|
||||
chr_y = (pen_y + (fg->glyph_out->top));
|
||||
chr_w = fg->glyph_out->bitmap.width + (kern);
|
||||
/* if (text[chr]) */
|
||||
{
|
||||
int advw;
|
||||
advw = ((fg->glyph->advance.x + (kern << 16)) >> 16);
|
||||
if (chr_w < advw) chr_w = advw;
|
||||
}
|
||||
#if 0 /* This looks like a hack, we don't want it. - leaving it here in case
|
||||
* I'm wrong */
|
||||
if (chr_x > prev_chr_end)
|
||||
{
|
||||
chr_w += (chr_x - prev_chr_end);
|
||||
chr_x = prev_chr_end;
|
||||
}
|
||||
#endif
|
||||
/* we need to see if the char at the visual position is the char wanted */
|
||||
if (char_index == position)
|
||||
{
|
||||
if (cx) *cx = chr_x;
|
||||
if (cy) *cy = -asc;
|
||||
if (cw) *cw = chr_w;
|
||||
if (ch) *ch = asc + desc;
|
||||
ret_val = 1;
|
||||
goto end;
|
||||
}
|
||||
prev_chr_end = chr_x + chr_w;
|
||||
prev_index = index;
|
||||
}
|
||||
end:
|
||||
|
||||
#ifdef BIDI_SUPPORT
|
||||
if (visual_to_logical) free(visual_to_logical);
|
||||
if (visual_text) free(visual_text);
|
||||
#endif
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* char pos of text at xy pos
|
||||
* BiDi handling: Since we are looking for the char at the specific coords,
|
||||
* we have to get the visual string (to which the coords relate to), do
|
||||
* reverse kerning query because we are working on the visual string, and then
|
||||
* we need to get the logical position of the char we found from the visual string.
|
||||
*/
|
||||
|
||||
EAPI int
|
||||
evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int prev_chr_end;
|
||||
int asc, desc;
|
||||
int char_index = 0; /* the index of the current char */
|
||||
const Eina_Unicode *text = in_text;
|
||||
int last_adv;
|
||||
int ret_val = -1;
|
||||
FT_UInt prev_index;
|
||||
RGBA_Font_Int *fi;
|
||||
FT_Face pface = NULL;
|
||||
|
||||
#ifdef BIDI_SUPPORT
|
||||
int len = 0;
|
||||
EvasBiDiStrIndex *visual_to_logical = NULL;
|
||||
Eina_Unicode *visual_text;
|
||||
|
||||
visual_text = eina_unicode_strdup(in_text);
|
||||
|
||||
if (visual_text)
|
||||
{
|
||||
evas_bidi_props_reorder_line(visual_text, intl_props, &visual_to_logical);
|
||||
text = visual_text;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = in_text;
|
||||
}
|
||||
len = eina_unicode_strlen(text);
|
||||
#endif
|
||||
|
||||
fi = fn->fonts->data;
|
||||
|
||||
pen_x = 0;
|
||||
pen_y = 0;
|
||||
// evas_common_font_size_use(fn);
|
||||
if (fi->src->current_size != fi->size)
|
||||
{
|
||||
FTLOCK();
|
||||
FT_Activate_Size(fi->ft.size);
|
||||
FTUNLOCK();
|
||||
fi->src->current_size = fi->size;
|
||||
}
|
||||
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
|
||||
last_adv = 0;
|
||||
prev_index = 0;
|
||||
prev_chr_end = 0;
|
||||
asc = evas_common_font_max_ascent_get(fn);
|
||||
desc = evas_common_font_max_descent_get(fn);
|
||||
|
||||
for (char_index = 0; *text; text++, char_index++)
|
||||
{
|
||||
int pchr;
|
||||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl, kern;
|
||||
|
||||
pchr = chr;
|
||||
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
gl = *text;
|
||||
if (gl == 0) break;
|
||||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
LKL(fi->ft_mutex);
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
if (!fg)
|
||||
{
|
||||
LKU(fi->ft_mutex);
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: Why not FT_Activate_Size here ?
|
||||
kern = 0;
|
||||
/* hmmm kerning means i can't sanely do my own cached metric tables! */
|
||||
|
@ -454,10 +535,14 @@ evas_common_font_query_text_at_pos(RGBA_Font *fn, const char *in_text, int x, in
|
|||
if ((use_kerning) && (prev_index) && (index) &&
|
||||
(pface == fi->src->ft.face))
|
||||
{
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
#ifdef BIDI_SUPPORT
|
||||
/* if it's rtl, the kerning matching should be reversed, i.e prev
|
||||
* index is now the index and the other way around. */
|
||||
if (evas_intl_is_rtl_char(level_list, char_index))
|
||||
* index is now the index and the other way around.
|
||||
* There is a slight exception when there are compositing chars
|
||||
* involved.*/
|
||||
if (intl_props &&
|
||||
evas_bidi_is_rtl_char(intl_props->embedding_levels, char_index) &&
|
||||
fg->glyph->advance.x >> 16 > 0)
|
||||
{
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
|
@ -470,16 +555,21 @@ evas_common_font_query_text_at_pos(RGBA_Font *fn, const char *in_text, int x, in
|
|||
pen_x += kern;
|
||||
}
|
||||
}
|
||||
|
||||
pface = fi->src->ft.face;
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
LKU(fi->ft_mutex);
|
||||
if (!fg) continue;
|
||||
|
||||
/* If the current one is not a compositing char, do the previous advance
|
||||
* and set the current advance as the next advance to do */
|
||||
if (fg->glyph->advance.x >> 16 > 0)
|
||||
{
|
||||
pen_x += last_adv;
|
||||
last_adv = fg->glyph->advance.x >> 16;
|
||||
}
|
||||
if (kern < 0) kern = 0;
|
||||
|
||||
chr_x = ((pen_x - kern) + (fg->glyph_out->left));
|
||||
chr_y = (pen_y + (fg->glyph_out->top));
|
||||
chr_w = fg->glyph_out->bitmap.width + kern;
|
||||
|
||||
/* if (text[chr]) */
|
||||
{
|
||||
int advw;
|
||||
|
@ -487,43 +577,38 @@ evas_common_font_query_text_at_pos(RGBA_Font *fn, const char *in_text, int x, in
|
|||
advw = ((fg->glyph->advance.x + (kern << 16)) >> 16);
|
||||
if (chr_w < advw) chr_w = advw;
|
||||
}
|
||||
#if 0 /* This looks like a hack, we don't want it. - leaving it here in case
|
||||
* I'm wrong */
|
||||
if (chr_x > prev_chr_end)
|
||||
{
|
||||
chr_w += (chr_x - prev_chr_end);
|
||||
chr_x = prev_chr_end;
|
||||
}
|
||||
#endif
|
||||
if ((x >= chr_x) && (x <= (chr_x + chr_w)) &&
|
||||
(y >= -asc) && (y <= desc))
|
||||
{
|
||||
int position = char_index;
|
||||
if (cx) *cx = chr_x;
|
||||
if (cy) *cy = -asc;
|
||||
if (cw) *cw = chr_w;
|
||||
if (ch) *ch = asc + desc;
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
{
|
||||
/* we found the char position of the wanted char in the
|
||||
* visual string, we now need to translate it to the
|
||||
* position in the logical string */
|
||||
int i;
|
||||
int position = evas_intl_position_visual_to_logical(visual_to_logical, char_index);
|
||||
|
||||
/* ensure even if the list won't run */
|
||||
for (pchr = 0, i = 0; i < position; i++)
|
||||
evas_common_font_utf8_get_next((unsigned char *)in_text, &pchr);
|
||||
}
|
||||
#ifdef BIDI_SUPPORT
|
||||
/* we found the char position of the wanted char in the
|
||||
* visual string, we now need to translate it to the
|
||||
* position in the logical string */
|
||||
position = evas_bidi_position_visual_to_logical(visual_to_logical, position);
|
||||
#endif
|
||||
ret_val = pchr;
|
||||
ret_val = position;
|
||||
goto end;
|
||||
}
|
||||
prev_chr_end = chr_x + chr_w;
|
||||
pen_x += fg->glyph->advance.x >> 16;
|
||||
prev_index = index;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
if (level_list) free(level_list);
|
||||
#ifdef BIDI_SUPPORT
|
||||
if (visual_to_logical) free(visual_to_logical);
|
||||
if (visual_text) free(visual_text);
|
||||
#endif
|
||||
|
@ -531,17 +616,23 @@ end:
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/* last char pos of text at xy pos
|
||||
* Note: no need for special rtl handling
|
||||
* because the string is in logical order, which is correct */
|
||||
/* position of the last char in thext text that will fit in xy.
|
||||
* BiDi handling: We recieve the shaped string + other props from intl_props,
|
||||
* All we care about is char sizes + kerning so we only really need to get the
|
||||
* shaped string to utf8, and then just go through it like in english, as it's
|
||||
* just the logical string, nothing special about that.
|
||||
*/
|
||||
|
||||
EAPI int
|
||||
evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const char *text, int x, int y)
|
||||
evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props, int x, int y)
|
||||
{
|
||||
int use_kerning;
|
||||
int pen_x, pen_y;
|
||||
int prev_chr_end;
|
||||
int chr;
|
||||
int char_index;
|
||||
int asc, desc;
|
||||
int ret=-1;
|
||||
const Eina_Unicode *text = in_text;
|
||||
FT_UInt prev_index;
|
||||
RGBA_Font_Int *fi;
|
||||
FT_Face pface = NULL;
|
||||
|
@ -556,16 +647,14 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const char *text, int x, in
|
|||
prev_chr_end = 0;
|
||||
asc = evas_common_font_max_ascent_get(fn);
|
||||
desc = evas_common_font_max_descent_get(fn);
|
||||
for (chr = 0; text[chr];)
|
||||
for (char_index = 0; *text; text++, char_index++)
|
||||
{
|
||||
int pchr;
|
||||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int chr_x, chr_y, chr_w;
|
||||
int gl, kern;
|
||||
|
||||
pchr = chr;
|
||||
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
||||
gl = *text;
|
||||
if (gl == 0) break;
|
||||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
LKL(fi->ft_mutex);
|
||||
|
@ -582,13 +671,14 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const char *text, int x, in
|
|||
/* you want performance */
|
||||
if ((use_kerning) && (prev_index) && (index) &&
|
||||
(pface == fi->src->ft.face))
|
||||
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
pen_x += kern;
|
||||
|
||||
{
|
||||
/* No need for special RTL handling because we are working on the logical string*/
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
pface = fi->src->ft.face;
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
LKU(fi->ft_mutex);
|
||||
if (!fg) continue;
|
||||
|
||||
if (kern < 0) kern = 0;
|
||||
chr_x = ((pen_x - kern) + (fg->glyph_out->left));
|
||||
|
@ -609,11 +699,14 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const char *text, int x, in
|
|||
if ((x >= chr_x) && (x <= (chr_x + chr_w)) &&
|
||||
(y >= -asc) && (y <= desc))
|
||||
{
|
||||
return pchr;
|
||||
ret = char_index;
|
||||
goto end;
|
||||
}
|
||||
prev_chr_end = chr_x + chr_w;
|
||||
pen_x += fg->glyph->advance.x >> 16;
|
||||
prev_index = index;
|
||||
}
|
||||
return -1;
|
||||
end:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "evas_common.h"
|
||||
#include "evas_intl_utils.h"
|
||||
|
||||
#include "evas_font_private.h"
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
#include <fribidi/fribidi.h>
|
||||
|
||||
#define UTF8_BYTES_PER_CHAR 4
|
||||
|
||||
/* FIXME: fribidi_utf8_to_unicode should use char len and not byte len!*/
|
||||
char *
|
||||
evas_intl_utf8_to_visual(const char *text,
|
||||
int *ret_len,
|
||||
EvasIntlParType *direction,
|
||||
EvasIntlStrIndex **position_L_to_V_list,
|
||||
EvasIntlStrIndex **position_V_to_L_list,
|
||||
EvasIntlLevel **embedding_level_list)
|
||||
{
|
||||
FriBidiChar *unicode_in, *unicode_out;
|
||||
EvasIntlStrIndex *tmp_L_to_V_list = NULL;
|
||||
EvasIntlStrIndex *tmp_V_to_L_list = NULL;
|
||||
EvasIntlLevel *tmp_level_list = NULL;
|
||||
char *text_out;
|
||||
size_t len;
|
||||
size_t byte_len;
|
||||
|
||||
if (!text)
|
||||
return NULL;
|
||||
|
||||
len = evas_string_char_len_get(text);
|
||||
|
||||
byte_len = strlen(text); /* we need the actual number of bytes, not number of chars */
|
||||
|
||||
unicode_in = (FriBidiChar *)alloca(sizeof(FriBidiChar) * (len + 1));
|
||||
FBDLOCK();
|
||||
len = fribidi_utf8_to_unicode(text, byte_len, unicode_in);
|
||||
FBDUNLOCK();
|
||||
unicode_in[len] = 0;
|
||||
|
||||
unicode_out = (FriBidiChar *)alloca(sizeof(FriBidiChar) * (len + 1));
|
||||
|
||||
if (embedding_level_list)
|
||||
{
|
||||
*embedding_level_list = (EvasIntlLevel *)malloc(sizeof(EvasIntlLevel) * len);
|
||||
if (!*embedding_level_list)
|
||||
{
|
||||
len = -1;
|
||||
goto error1;
|
||||
}
|
||||
tmp_level_list = *embedding_level_list;
|
||||
}
|
||||
|
||||
if (position_L_to_V_list)
|
||||
{
|
||||
*position_L_to_V_list = (EvasIntlStrIndex *)malloc(sizeof(EvasIntlStrIndex) * len);
|
||||
if (!*position_L_to_V_list)
|
||||
{
|
||||
len = -1;
|
||||
goto error2;
|
||||
}
|
||||
tmp_L_to_V_list = *position_L_to_V_list;
|
||||
}
|
||||
|
||||
if (position_V_to_L_list)
|
||||
{
|
||||
*position_V_to_L_list = (EvasIntlStrIndex *)malloc(sizeof(EvasIntlStrIndex) * len);
|
||||
if (!*position_V_to_L_list)
|
||||
{
|
||||
len = -1;
|
||||
goto error2;
|
||||
}
|
||||
tmp_V_to_L_list = *position_V_to_L_list;
|
||||
}
|
||||
|
||||
FBDLOCK();
|
||||
if (!fribidi_log2vis(unicode_in, len, direction,
|
||||
unicode_out, tmp_L_to_V_list, tmp_V_to_L_list, tmp_level_list))
|
||||
{
|
||||
FBDUNLOCK();
|
||||
len = -2;
|
||||
goto error2;
|
||||
}
|
||||
FBDUNLOCK();
|
||||
|
||||
text_out = malloc(UTF8_BYTES_PER_CHAR * len + 1);
|
||||
if (!text_out)
|
||||
{
|
||||
len = -1;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
FBDLOCK();
|
||||
fribidi_unicode_to_utf8(unicode_out, len, text_out);
|
||||
FBDUNLOCK();
|
||||
|
||||
*ret_len = len;
|
||||
return text_out;
|
||||
|
||||
/* ERROR HANDLING */
|
||||
error1:
|
||||
free(*position_V_to_L_list);
|
||||
*position_V_to_L_list = NULL;
|
||||
error2:
|
||||
free(*position_L_to_V_list);
|
||||
*position_L_to_V_list = NULL;
|
||||
free(*embedding_level_list);
|
||||
*embedding_level_list = NULL;
|
||||
|
||||
*ret_len = len;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
evas_intl_is_rtl_char(EvasIntlLevel *embedded_level_list, EvasIntlStrIndex i)
|
||||
{
|
||||
if(embedded_level_list || i < 0)
|
||||
return 0;
|
||||
return FRIBIDI_IS_RTL(embedded_level_list[i]);
|
||||
}
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef _EVAS_INTL_UTILS
|
||||
#define _EVAS_INTL_UTILS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FRIBIDI
|
||||
# define USE_FRIBIDI
|
||||
# define INTERNATIONAL_SUPPORT
|
||||
#endif
|
||||
|
||||
#ifdef USE_FRIBIDI
|
||||
# include <fribidi/fribidi.h>
|
||||
|
||||
/* abstract fribidi */
|
||||
typedef FriBidiChar EvasIntlChar;
|
||||
typedef FriBidiCharType EvasIntlParType;
|
||||
typedef FriBidiStrIndex EvasIntlStrIndex;
|
||||
typedef FriBidiLevel EvasIntlLevel;
|
||||
|
||||
|
||||
# define evas_intl_position_logical_to_visual(list, position) \
|
||||
(list) ? list[position] : position;
|
||||
|
||||
# define evas_intl_position_visual_to_logical(list, position) \
|
||||
(list) ? list[position] : position;
|
||||
|
||||
|
||||
int
|
||||
evas_intl_is_rtl_char(EvasIntlLevel *embedded_level_list, EvasIntlStrIndex i);
|
||||
|
||||
char *
|
||||
evas_intl_utf8_to_visual(const char *text,
|
||||
int *ret_len,
|
||||
EvasIntlParType *direction,
|
||||
EvasIntlStrIndex **position_L_to_V_list,
|
||||
EvasIntlStrIndex **position_V_to_L_list,
|
||||
EvasIntlLevel **embedding_level_list);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1399,19 +1399,19 @@ evas_common_pipe_text_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Threa
|
|||
#endif
|
||||
evas_common_font_draw(dst, &(context),
|
||||
op->op.text.font, op->op.text.x, op->op.text.y,
|
||||
op->op.text.text);
|
||||
op->op.text.text, op->op.text.intl_props);
|
||||
}
|
||||
else
|
||||
{
|
||||
evas_common_font_draw(dst, &(op->context),
|
||||
op->op.text.font, op->op.text.x, op->op.text.y,
|
||||
op->op.text.text);
|
||||
op->op.text.text, op->op.text.intl_props);
|
||||
}
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
|
||||
RGBA_Font *fn, int x, int y, const char *text)
|
||||
RGBA_Font *fn, int x, int y, const char *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
RGBA_Pipe_Op *op;
|
||||
|
||||
|
@ -1421,6 +1421,7 @@ evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
|
|||
op->op.text.x = x;
|
||||
op->op.text.y = y;
|
||||
op->op.text.text = strdup(text);
|
||||
op->op.text.intl_props = intl_props;
|
||||
#ifdef EVAS_FRAME_QUEUING
|
||||
LKL(fn->ref_fq_add);
|
||||
fn->ref_fq[0]++;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef _EVAS_PIPE_H
|
||||
#define _EVAS_PIPE_H
|
||||
#include "evas_bidi_utils.h"
|
||||
|
||||
#ifdef BUILD_PTHREAD
|
||||
typedef struct _Thinfo
|
||||
|
@ -88,7 +89,7 @@ EAPI void evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int
|
|||
EAPI void evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y);
|
||||
EAPI void evas_common_pipe_grad_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h, RGBA_Gradient *gr);
|
||||
EAPI void evas_common_pipe_grad2_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h, RGBA_Gradient2 *gr);
|
||||
EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text);
|
||||
EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text, const Evas_BiDi_Props *intl_props);
|
||||
EAPI void evas_common_pipe_image_load(RGBA_Image *im);
|
||||
EAPI void evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int smooth, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
|
||||
EAPI void evas_common_pipe_map4_draw(RGBA_Image *src, RGBA_Image *dst,
|
||||
|
|
|
@ -197,36 +197,86 @@ evas_imaging_font_line_advance_get(const Evas_Imaging_Font *fn)
|
|||
EAPI void
|
||||
evas_imaging_font_string_advance_get(const Evas_Imaging_Font *fn, const char *str, int *x, int *y)
|
||||
{
|
||||
Evas_BiDi_Props intl_props;
|
||||
Eina_Unicode *ustr;
|
||||
if (!fn) return;
|
||||
evas_common_font_query_advance(fn->font, str, x, y);
|
||||
ustr = evas_common_encoding_utf8_to_unicode(str, NULL);
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_update_props(ustr, &intl_props);
|
||||
#endif
|
||||
evas_common_font_query_advance(fn->font, ustr, &intl_props, x, y);
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_props_clean(&intl_props);
|
||||
#endif
|
||||
if (ustr) free(ustr);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_imaging_font_string_size_query(const Evas_Imaging_Font *fn, const char *str, int *w, int *h)
|
||||
{
|
||||
Evas_BiDi_Props intl_props;
|
||||
Eina_Unicode *ustr;
|
||||
if (!fn) return;
|
||||
evas_common_font_query_size(fn->font, str, w, h);
|
||||
ustr = evas_common_encoding_utf8_to_unicode(str, NULL);
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_update_props(ustr, &intl_props);
|
||||
#endif
|
||||
evas_common_font_query_size(fn->font, ustr, &intl_props, w, h);
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_props_clean(&intl_props);
|
||||
#endif
|
||||
if (ustr) free(ustr);
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_imaging_font_string_inset_get(const Evas_Imaging_Font *fn, const char *str)
|
||||
{
|
||||
Eina_Unicode *ustr;
|
||||
int ret;
|
||||
|
||||
if (!fn) return 0;
|
||||
return evas_common_font_query_inset(fn->font, str);
|
||||
ustr = evas_common_encoding_utf8_to_unicode(str, NULL);
|
||||
ret = evas_common_font_query_inset(fn->font, ustr);
|
||||
if (ustr) free(ustr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_imaging_font_string_char_coords_get(const Evas_Imaging_Font *fn, const char *str, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
int ret;
|
||||
Evas_BiDi_Props intl_props;
|
||||
Eina_Unicode *ustr;
|
||||
if (!fn) return 0;
|
||||
return evas_common_font_query_char_coords(fn->font, str, pos, cx, cy, cw, ch);
|
||||
ustr = evas_common_encoding_utf8_to_unicode(str, NULL);
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_update_props(ustr, &intl_props);
|
||||
#endif
|
||||
ret = evas_common_font_query_char_coords(fn->font, ustr, &intl_props, pos, cx, cy, cw, ch);
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_props_clean(&intl_props);
|
||||
#endif
|
||||
if (ustr) free(ustr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_imaging_font_string_char_at_coords_get(const Evas_Imaging_Font *fn, const char *str, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
int ret;
|
||||
Evas_BiDi_Props intl_props;
|
||||
Eina_Unicode *ustr;
|
||||
if (!fn) return -1;
|
||||
return evas_common_font_query_text_at_pos(fn->font, str, x, y, cx, cy, cw, ch);
|
||||
ustr = evas_common_encoding_utf8_to_unicode(str, NULL);
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_update_props(ustr, &intl_props);
|
||||
#endif
|
||||
ret = evas_common_font_query_char_at_coords(fn->font, ustr, &intl_props, x, y, cx, cy, cw, ch);
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_props_clean(&intl_props);
|
||||
#endif
|
||||
if (ustr) free(ustr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
|
|
@ -53,7 +53,9 @@ extern EAPI int _evas_log_dom_global;
|
|||
#endif
|
||||
#define CRIT(...) EINA_LOG_DOM_CRIT(_EVAS_DEFAULT_LOG_DOM, __VA_ARGS__)
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Unicode stuff **************************/
|
||||
#include "../engines/common/evas_encoding.h"
|
||||
/*****************************************************************/
|
||||
|
||||
#include "evas_options.h"
|
||||
|
||||
|
@ -670,6 +672,7 @@ struct _RGBA_Draw_Context
|
|||
|
||||
#ifdef BUILD_PIPE_RENDER
|
||||
#include "../engines/common/evas_map_image.h"
|
||||
#include "../engines/common/evas_bidi_utils.h"
|
||||
|
||||
struct _RGBA_Pipe_Op
|
||||
{
|
||||
|
@ -698,7 +701,8 @@ struct _RGBA_Pipe_Op
|
|||
struct {
|
||||
RGBA_Font *font;
|
||||
int x, y;
|
||||
char *text;
|
||||
Eina_Unicode *text;
|
||||
Evas_BiDi_Props *intl_props;
|
||||
} text;
|
||||
struct {
|
||||
RGBA_Image *src;
|
||||
|
@ -1332,4 +1336,5 @@ void evas_font_dir_cache_free(void);
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "../file/evas_module.h"
|
||||
#include "../file/evas_path.h"
|
||||
#include "../engines/common/evas_bidi_utils.h"
|
||||
|
||||
#ifdef EVAS_MAGIC_DEBUG
|
||||
/* complain when peole pass in wrong object types etc. */
|
||||
|
@ -703,13 +704,13 @@ struct _Evas_Func
|
|||
int (*font_descent_get) (void *data, void *font);
|
||||
int (*font_max_ascent_get) (void *data, void *font);
|
||||
int (*font_max_descent_get) (void *data, void *font);
|
||||
void (*font_string_size_get) (void *data, void *font, const char *text, int *w, int *h);
|
||||
int (*font_inset_get) (void *data, void *font, const char *text);
|
||||
int (*font_h_advance_get) (void *data, void *font, const char *text);
|
||||
int (*font_v_advance_get) (void *data, void *font, const char *text);
|
||||
int (*font_char_coords_get) (void *data, void *font, const char *text, int pos, int *cx, int *cy, int *cw, int *ch);
|
||||
int (*font_char_at_coords_get) (void *data, void *font, const char *text, int x, int y, int *cx, int *cy, int *cw, int *ch);
|
||||
void (*font_draw) (void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text);
|
||||
void (*font_string_size_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h);
|
||||
int (*font_inset_get) (void *data, void *font, const Eina_Unicode *text);
|
||||
int (*font_h_advance_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props);
|
||||
int (*font_v_advance_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props);
|
||||
int (*font_char_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch);
|
||||
int (*font_char_at_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch);
|
||||
void (*font_draw) (void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props);
|
||||
|
||||
void (*font_cache_flush) (void *data);
|
||||
void (*font_cache_set) (void *data, int bytes);
|
||||
|
@ -724,7 +725,7 @@ struct _Evas_Func
|
|||
|
||||
void (*image_scale_hint_set) (void *data, void *image, int hint);
|
||||
int (*image_scale_hint_get) (void *data, void *image);
|
||||
int (*font_last_up_to_pos) (void *data, void *font, const char *text, int x, int y);
|
||||
int (*font_last_up_to_pos) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y);
|
||||
|
||||
void (*image_map4_draw) (void *data, void *context, void *surface, void *image, RGBA_Map_Point *p, int smooth, int level);
|
||||
void *(*image_map_surface_new) (void *data, int w, int h, int alpha);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "evas_common.h" /* Also includes international specific stuff */
|
||||
#include "evas_engine.h"
|
||||
#include "evas_private.h"
|
||||
#include "Evas_Engine_Direct3D.h"
|
||||
|
@ -388,7 +389,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text)
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
Render_Engine *re = (Render_Engine *)data;
|
||||
RGBA_Image im;
|
||||
|
@ -402,7 +403,7 @@ eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y
|
|||
evas_direct3d_font_texture_new,
|
||||
evas_direct3d_font_texture_free,
|
||||
evas_direct3d_font_texture_draw);
|
||||
evas_common_font_draw(&im, context, font, x, y, text);
|
||||
evas_common_font_draw(&im, context, font, x, y, text, intl_props);
|
||||
evas_common_draw_context_font_ext_set(context, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include "evas_engine.h"
|
||||
#include "evas_common.h" /* Also includes international specific stuff */
|
||||
|
||||
/* Uses Evas own image_draw primitive, for comparison purposes only. */
|
||||
//#define DFB_USE_EVAS_IMAGE_DRAW 1
|
||||
|
@ -1041,7 +1042,7 @@ evas_engine_dfb_output_idle_flush(void *data)
|
|||
* memory.
|
||||
*/
|
||||
static void
|
||||
evas_engine_dfb_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text)
|
||||
evas_engine_dfb_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
DirectFB_Engine_Image_Entry *eim = surface;
|
||||
IDirectFBSurface *screen;
|
||||
|
@ -1053,7 +1054,7 @@ evas_engine_dfb_font_draw(void *data, void *context, void *surface, void *font,
|
|||
if (!_dfb_lock_and_sync_image(screen, im, DSLF_READ | DSLF_WRITE))
|
||||
return;
|
||||
|
||||
evas_common_font_draw(im, context, font, x, y, text);
|
||||
evas_common_font_draw(im, context, font, x, y, text, intl_props);
|
||||
evas_common_cpu_end_opt();
|
||||
|
||||
im->image.data = NULL;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "evas_common.h" /* Also includes international specific stuff */
|
||||
#include "evas_engine.h"
|
||||
|
||||
int _evas_engine_GL_glew_log_dom = -1;
|
||||
|
@ -986,7 +987,7 @@ eng_image_map_surface_free(void *data __UNUSED__, void *surface)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text)
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
|
@ -1006,7 +1007,7 @@ eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y
|
|||
evas_gl_font_texture_new,
|
||||
evas_gl_font_texture_free,
|
||||
evas_gl_font_texture_draw);
|
||||
evas_common_font_draw(im, context, font, x, y, text);
|
||||
evas_common_font_draw(im, context, font, x, y, text, intl_props);
|
||||
evas_common_draw_context_font_ext_set(context,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_common.h" /* Also includes international specific stuff */
|
||||
#include "evas_engine.h"
|
||||
|
||||
#include <dlfcn.h> /* dlopen,dlclose,etc */
|
||||
|
@ -1172,7 +1172,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text)
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
|
@ -1192,7 +1192,7 @@ eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y
|
|||
evas_gl_font_texture_new,
|
||||
evas_gl_font_texture_free,
|
||||
evas_gl_font_texture_draw);
|
||||
evas_common_font_draw(im, context, font, x, y, text);
|
||||
evas_common_font_draw(im, context, font, x, y, text, intl_props);
|
||||
evas_common_draw_context_font_ext_set(context,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "evas_common.h" /* Also includes international specific stuff */
|
||||
#include "evas_engine.h"
|
||||
|
||||
#include <dlfcn.h> /* dlopen,dlclose,etc */
|
||||
|
@ -1949,7 +1950,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text)
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
|
@ -1970,7 +1971,7 @@ eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y
|
|||
evas_gl_font_texture_new,
|
||||
evas_gl_font_texture_free,
|
||||
evas_gl_font_texture_draw);
|
||||
evas_common_font_draw(im, context, font, x, y, text);
|
||||
evas_common_font_draw(im, context, font, x, y, text, intl_props);
|
||||
evas_common_draw_context_font_ext_set(context,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -1249,7 +1249,7 @@ eng_font_max_descent_get(void *data, void *font)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_string_size_get(void *data, void *font, const char *text, int *w, int *h)
|
||||
eng_font_string_size_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int *w, int *h)
|
||||
{
|
||||
Render_Engine *re = (Render_Engine *)data;
|
||||
Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font;
|
||||
|
@ -1279,28 +1279,28 @@ eng_font_inset_get(void *data, void *font, const char *text)
|
|||
}
|
||||
|
||||
static int
|
||||
eng_font_h_advance_get(void *data, void *font, const char *text)
|
||||
eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
int w;
|
||||
|
||||
eng_font_string_size_get(data, font, text, &w, NULL);
|
||||
eng_font_string_size_get(data, font, text, intl_props, &w, NULL);
|
||||
|
||||
return w + 2; // FIXME: shouldn't need a constant here. from where do we get word spacing?
|
||||
// it seems we lose the space between differently-styled text in a text block. Why?
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_v_advance_get(void *data, void *font, const char *text)
|
||||
eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
int h;
|
||||
|
||||
eng_font_string_size_get(data, font, text, NULL, &h);
|
||||
eng_font_string_size_get(data, font, text, intl_props, NULL, &h);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_char_coords_get(void *data, void *font, const char *text, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font;
|
||||
|
||||
|
@ -1320,7 +1320,7 @@ eng_font_char_coords_get(void *data, void *font, const char *text, int pos, int
|
|||
}
|
||||
|
||||
static int
|
||||
eng_font_char_at_coords_get(void *data, void *font, const char *text, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
// Return the index of the character at the given point, also lookup it's origin x, y, w, and h.
|
||||
Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font;
|
||||
|
@ -1332,8 +1332,8 @@ eng_font_char_at_coords_get(void *data, void *font, const char *text, int x, int
|
|||
int stringIndex = (int) CTLineGetStringIndexForPosition(line, CGPointMake(x, y));
|
||||
|
||||
// In order to get the character's size and position, look up the position of this character and the next one
|
||||
eng_font_char_coords_get(data, font, text, stringIndex, cx, cy, NULL, NULL);
|
||||
eng_font_char_coords_get(data, font, text, stringIndex + 1, cw, NULL, NULL, NULL);
|
||||
eng_font_char_coords_get(data, font, text, intl_props, stringIndex, cx, cy, NULL, NULL);
|
||||
eng_font_char_coords_get(data, font, text, intl_props, stringIndex + 1, cw, NULL, NULL, NULL);
|
||||
|
||||
if (cw && cx) *cw -= *cx;
|
||||
if (ch) *ch = loaded_font->size;
|
||||
|
@ -1359,7 +1359,7 @@ eng_font_hinting_can_hint(void *data, int hinting)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text)
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
Render_Engine *re = (Render_Engine *)data;
|
||||
Evas_Quartz_Context *ctxt = (Evas_Quartz_Context *)context;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _EVAS_QUARTZ_PRIVATE_H_
|
||||
#define _EVAS_QUARTZ_PRIVATE_H_
|
||||
|
||||
#include "evas_common.h"/* Also includes international specific stuff */
|
||||
#include "evas_engine.h"
|
||||
|
||||
CG_EXTERN void CGContextResetClip (CGContextRef); // undocumented CoreGraphics function to clear clip rect/*
|
||||
|
@ -93,7 +94,7 @@ static int eng_font_ascent_get(void *data, void *font);
|
|||
static int eng_font_descent_get(void *data, void *font);
|
||||
static int eng_font_max_ascent_get(void *data, void *font);
|
||||
static int eng_font_max_descent_get(void *data, void *font);
|
||||
static void eng_font_string_size_get(void *data, void *font, const char *text, int *w, int *h);
|
||||
static void eng_font_string_size_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int *w, int *h);
|
||||
static int eng_font_inset_get(void *data, void *font, const char *text);
|
||||
static int eng_font_h_advance_get(void *data, void *font, const char *text);
|
||||
static int eng_font_v_advance_get(void *data, void *font, const char *text);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_common.h"/* Also includes international specific stuff */
|
||||
#include "evas_common_soft16.h"
|
||||
|
||||
/*
|
||||
|
@ -762,55 +762,55 @@ eng_font_max_descent_get(void *data __UNUSED__, void *font)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_string_size_get(void *data __UNUSED__, void *font, const char *text, int *w, int *h)
|
||||
eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h)
|
||||
{
|
||||
evas_common_font_query_size(font, text, w, h);
|
||||
evas_common_font_query_size(font, text, intl_props, w, h);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_inset_get(void *data __UNUSED__, void *font, const char *text)
|
||||
eng_font_inset_get(void *data __UNUSED__, void *font, const Eina_Unicode *text)
|
||||
{
|
||||
return evas_common_font_query_inset(font, text);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_h_advance_get(void *data __UNUSED__, void *font, const char *text)
|
||||
eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
int h, v;
|
||||
|
||||
evas_common_font_query_advance(font, text, &h, &v);
|
||||
evas_common_font_query_advance(font, text, intl_props, &h, &v);
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_v_advance_get(void *data __UNUSED__, void *font, const char *text)
|
||||
eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
int h, v;
|
||||
|
||||
evas_common_font_query_advance(font, text, &h, &v);
|
||||
evas_common_font_query_advance(font, text, intl_props, &h, &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_char_coords_get(void *data __UNUSED__, void *font, const char *text, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
return evas_common_font_query_char_coords(font, text, pos, cx, cy, cw, ch);
|
||||
return evas_common_font_query_char_coords(font, text, intl_props, pos, cx, cy, cw, ch);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const char *text, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
return evas_common_font_query_text_at_pos(font, text, x, y, cx, cy, cw, ch);
|
||||
return evas_common_font_query_char_at_coords(font, text, intl_props, x, y, cx, cy, cw, ch);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const char *text, int x, int y)
|
||||
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y)
|
||||
{
|
||||
return evas_common_font_query_last_up_to_pos(font, text, x, y);
|
||||
return evas_common_font_query_last_up_to_pos(font, text, intl_props, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text)
|
||||
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
static RGBA_Image *im = NULL;
|
||||
Soft16_Image *dst = surface;
|
||||
|
@ -823,7 +823,7 @@ eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, i
|
|||
soft16_font_glyph_new,
|
||||
soft16_font_glyph_free,
|
||||
soft16_font_glyph_draw);
|
||||
evas_common_font_draw(im, context, font, x, y, text);
|
||||
evas_common_font_draw(im, context, font, x, y, text, intl_props);
|
||||
evas_common_draw_context_font_ext_set(context,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <time.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "evas_common.h"
|
||||
#include "evas_common.h"/* Also includes international specific stuff */
|
||||
#include "evas_engine.h"
|
||||
int _evas_engine_soft16_sdl_log_dom = -1;
|
||||
|
||||
|
@ -877,7 +877,7 @@ evas_engine_sdl16_image_format_get(void *data __UNUSED__, void *image __UNUSED__
|
|||
}
|
||||
|
||||
static void
|
||||
evas_engine_sdl16_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text)
|
||||
evas_engine_sdl16_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
static RGBA_Image *im = NULL;
|
||||
SDL_Engine_Image_Entry *eim = surface;
|
||||
|
@ -899,7 +899,7 @@ evas_engine_sdl16_font_draw(void *data __UNUSED__, void *context, void *surface,
|
|||
soft16_font_glyph_new,
|
||||
soft16_font_glyph_free,
|
||||
soft16_font_glyph_draw);
|
||||
evas_common_font_draw(im, context, font, x, y, text);
|
||||
evas_common_font_draw(im, context, font, x, y, text, intl_props);
|
||||
evas_common_draw_context_font_ext_set(context,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_common.h" /* Also includes international specific stuff */
|
||||
#include "evas_private.h"
|
||||
|
||||
/*
|
||||
|
@ -983,55 +983,55 @@ eng_font_max_descent_get(void *data __UNUSED__, void *font)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_string_size_get(void *data __UNUSED__, void *font, const char *text, int *w, int *h)
|
||||
eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h)
|
||||
{
|
||||
evas_common_font_query_size(font, text, w, h);
|
||||
evas_common_font_query_size(font, text, intl_props, w, h);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_inset_get(void *data __UNUSED__, void *font, const char *text)
|
||||
eng_font_inset_get(void *data __UNUSED__, void *font, const Eina_Unicode *text)
|
||||
{
|
||||
return evas_common_font_query_inset(font, text);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_h_advance_get(void *data __UNUSED__, void *font, const char *text)
|
||||
eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
int h, v;
|
||||
|
||||
evas_common_font_query_advance(font, text, &h, &v);
|
||||
evas_common_font_query_advance(font, text, intl_props, &h, &v);
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_v_advance_get(void *data __UNUSED__, void *font, const char *text)
|
||||
eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
int h, v;
|
||||
|
||||
evas_common_font_query_advance(font, text, &h, &v);
|
||||
evas_common_font_query_advance(font, text, intl_props, &h, &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_char_coords_get(void *data __UNUSED__, void *font, const char *text, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
return evas_common_font_query_char_coords(font, text, pos, cx, cy, cw, ch);
|
||||
return evas_common_font_query_char_coords(font, text, intl_props, pos, cx, cy, cw, ch);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const char *text, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
return evas_common_font_query_text_at_pos(font, text, x, y, cx, cy, cw, ch);
|
||||
return evas_common_font_query_char_at_coords(font, text, intl_props, x, y, cx, cy, cw, ch);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const char *text, int x, int y)
|
||||
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y)
|
||||
{
|
||||
return evas_common_font_query_last_up_to_pos(font, text, x, y);
|
||||
return evas_common_font_query_last_up_to_pos(font, text, intl_props, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text)
|
||||
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
#ifdef BUILD_PIPE_RENDER
|
||||
if ((cpunum > 1)
|
||||
|
@ -1039,11 +1039,11 @@ eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, i
|
|||
&& evas_common_frameq_enabled()
|
||||
#endif
|
||||
)
|
||||
evas_common_pipe_text_draw(surface, context, font, x, y, text);
|
||||
evas_common_pipe_text_draw(surface, context, font, x, y, text, intl_props);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
evas_common_font_draw(surface, context, font, x, y, text);
|
||||
evas_common_font_draw(surface, context, font, x, y, text, intl_props);
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <time.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "evas_common.h"
|
||||
#include "evas_common.h" /* Also includes international specific stuff */
|
||||
#include "evas_engine.h"
|
||||
|
||||
int _evas_engine_soft_sdl_log_dom = -1;
|
||||
|
@ -739,7 +739,7 @@ evas_engine_sdl_image_format_get(void *data __UNUSED__, void *image __UNUSED__)
|
|||
}
|
||||
|
||||
static void
|
||||
evas_engine_sdl_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text)
|
||||
evas_engine_sdl_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
SDL_Engine_Image_Entry *eim = surface;
|
||||
int mustlock_im = 0;
|
||||
|
@ -751,7 +751,7 @@ evas_engine_sdl_font_draw(void *data __UNUSED__, void *context, void *surface, v
|
|||
_SDL_UPDATE_PIXELS(eim);
|
||||
}
|
||||
|
||||
evas_common_font_draw((RGBA_Image *) eim->cache_entry.src, context, font, x, y, text);
|
||||
evas_common_font_draw((RGBA_Image *) eim->cache_entry.src, context, font, x, y, text, intl_props);
|
||||
evas_common_cpu_end_opt();
|
||||
|
||||
if (mustlock_im)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_common.h" /* Also includes international specific stuff */
|
||||
#include "evas_private.h"
|
||||
|
||||
#include "Evas_Engine_XRender_X11.h"
|
||||
|
@ -1484,7 +1484,7 @@ eng_image_cache_get(void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow __UNUSED__, int oh __UNUSED__, const char *text)
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
|
||||
{
|
||||
Render_Engine *re;
|
||||
RGBA_Image *im;
|
||||
|
@ -1503,7 +1503,7 @@ eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y
|
|||
re->font_surface_new,
|
||||
re->font_surface_free,
|
||||
re->font_surface_draw);
|
||||
evas_common_font_draw(im, context, font, x, y, text);
|
||||
evas_common_font_draw(im, context, font, x, y, text, intl_props);
|
||||
evas_common_draw_context_font_ext_set(context,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
Loading…
Reference in New Issue