1. Started feeding Evas_Text_Props to the font engine instead of Evas_BiDi_Props because no we have more general text properties as well - i.e, OpenType stuff.
2. Full Harfbuzz integration which gets compiled in by default (if harfbuzz is present) but only works if the environment variable EVAS_USE_OT is set to 1 (because OT is way slower than regular text rendering).
3. Cleaned the font querying/drawing functions.
4. Added font_shaped function to all of the engines, which by default calls teh harfbuzz stuff (default on linux that is).
5. Moved some source files around a bit to make more sense.
SVN revision: 56455
Eina_Unicode *text; /*The shaped text */
size_t text_pos;
size_t visual_pos;
- Evas_BiDi_Props bidi_props;
+ Evas_Text_Props text_props;
Evas_Coord x, w, h, adv;
};
(pos < it->text_pos + eina_unicode_strlen(it->text)))
{
return ENFN->font_char_coords_get(ENDT, o->engine_data, it->text,
- &it->bidi_props, pos - it->text_pos, x, y, w, h);
+ &it->text_props, pos - it->text_pos, x, y, w, h);
}
}
return 0;
static void
_evas_object_text_item_clean(Evas_Object_Text_Item *it)
{
-#ifdef BIDI_SUPPORT
- evas_bidi_props_clean(&it->bidi_props);
-#endif
+ evas_common_text_props_content_unref(&it->text_props);
if (it->text)
{
free(it->text);
{
return ENFN->font_last_up_to_pos(ENDT,
o->engine_data,
- it->text, &it->bidi_props,
+ it->text, &it->text_props,
cx - x,
cy);
}
{
return ENFN->font_char_at_coords_get(ENDT,
o->engine_data,
- it->text, &it->bidi_props,
+ it->text, &it->text_props,
cx,
cy,
rx, ry,
{
Evas_Coord tmp;
tmp = ENFN->font_v_advance_get(ENDT, o->engine_data, it->text,
- &it->bidi_props);
+ &it->text_props);
if (tmp > adv)
{
adv = tmp;
it->text_pos = pos;
it->visual_pos = visual_pos;
eina_unicode_strncpy(it->text, str + pos, len);
-#ifdef BIDI_SUPPORT
- it->bidi_props.dir = (evas_bidi_is_rtl_char(
- o->bidi_par_props,
- 0,
- it->text_pos)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
- evas_bidi_shape_string(it->text, o->bidi_par_props, pos, len);
-#endif
+ evas_common_text_props_bidi_set(&it->text_props, o->bidi_par_props,
+ it->text_pos);
+ evas_common_text_props_script_set(&it->text_props, it->text);
+ ENFN->font_shape(ENDT, o->engine_data, it->text, &it->text_props,
+ o->bidi_par_props, it->text_pos, eina_unicode_strlen(it->text));
ENFN->font_string_size_get(ENDT,
o->engine_data,
- it->text, &it->bidi_props,
+ it->text, &it->text_props,
&it->w, &it->h);
it->adv = ENFN->font_h_advance_get(ENDT, o->engine_data, it->text,
- &it->bidi_props);
+ &it->text_props);
o->items = (Evas_Object_Text_Item *)
eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(it));
return it;
cutoff = len;
do
{
- cutoff = evas_common_script_end_of_run_get(
+ cutoff = evas_common_language_script_end_of_run_get(
text,
o->bidi_par_props,
pos, cutoff);
obj->cur.geometry.h, \
obj->cur.geometry.w, \
obj->cur.geometry.h, \
- it->text, &it->bidi_props);
+ it->text, &it->text_props);
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
{
/* shadows */
size_t visual_pos;
#endif
Evas_Coord adv, x, w, h;
- Evas_BiDi_Props bidi_props;
+ Evas_Text_Props text_props;
};
struct _Evas_Object_Textblock_Text_Item
/**
* @internal
+ * Free a layout item
+ * @param obj The evas object, must not be NULL.
+ * @param ln the layout line on which the item is in, must not be NULL.
+ * @param it the layout item to be freed
+ */
+static void
+_item_free(const Evas_Object *obj, Evas_Object_Textblock_Line *ln, Evas_Object_Textblock_Item *it)
+{
+ if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT)
+ {
+ Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it);
+
+ if (ti->text) free(ti->text);
+ _format_unref_free(obj, ti->format);
+ }
+ else
+ {
+ Evas_Object_Textblock_Format_Item *fi = _ITEM_FORMAT(it);
+
+ if (fi->item) eina_stringshare_del(fi->item);
+ }
+ evas_common_text_props_content_unref(&it->text_props);
+ if (ln)
+ {
+ ln->items = (Evas_Object_Textblock_Item *) eina_inlist_remove(
+ EINA_INLIST_GET(ln->items), EINA_INLIST_GET(ln->items));
+ }
+ free(it);
+}
+
+/**
+ * @internal
* Free a layout line.
* @param obj The evas object, must not be NULL.
* @param ln the layout line to be freed, must not be NULL.
while (ln->items)
{
Evas_Object_Textblock_Item *it = ln->items;
- if (ln->items->type == EVAS_TEXTBLOCK_ITEM_TEXT)
- {
- Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it);
-
- if (ti->text) free(ti->text);
- _format_unref_free(obj, ti->format);
- }
- else
- {
- Evas_Object_Textblock_Format_Item *fi = _ITEM_FORMAT(it);
-
- if (fi->item) eina_stringshare_del(fi->item);
- }
- ln->items = (Evas_Object_Textblock_Item *) eina_inlist_remove(
- EINA_INLIST_GET(ln->items), EINA_INLIST_GET(ln->items));
- free(it);
+ _item_free(obj, ln, it);
}
if (ln) free(ln);
}
{
if (fmt->font.font)
return c->ENFN->font_last_up_to_pos(c->ENDT, fmt->font.font, ti->text,
- &ti->parent.bidi_props,
+ &ti->parent.text_props,
c->w -
c->o->style_pad.l -
c->o->style_pad.r -
ts[cut] = 0;
ti->text = eina_unicode_strdup(ts);
free(ts);
+ c->ENFN->font_shape(c->ENDT, ti->format->font.font, ti->text,
+ &ti->parent.text_props, ti->parent.text_node->bidi_props,
+ ti->parent.text_pos, cut);
}
/**
adv = 0;
if (ti->format->font.font)
adv = c->ENFN->font_h_advance_get(c->ENDT, ti->format->font.font,
- ti->text, &ti->parent.bidi_props);
+ ti->text, &ti->parent.text_props);
tw = th = 0;
if (ti->format->font.font)
c->ENFN->font_string_size_get(c->ENDT, ti->format->font.font,
- ti->text, &ti->parent.bidi_props, &tw, &th);
+ ti->text, &ti->parent.text_props, &tw, &th);
it->w = tw;
it->h = th;
it->adv = adv;
/*FIXME: handle it in some way? */
if (it->type != EVAS_TEXTBLOCK_ITEM_TEXT)
return 0;
- if (ti->text) free(ti->text);
- _format_unref_free(c->obj, ti->format);
-
-#ifdef BIDI_SUPPORT
- /* FIXME: this also unrefs the paragraph props, we should either
- * really count the usage of the paragraph props in the items, or just
- * not use clean here. I prefer the latter but that might break if we'll
- * start doing fancy stuff in clean in the future. */
- /* evas_bidi_props_clean(&it->bidi_props); */
-#endif
- free(ti);
+ _item_free(c->obj, NULL, _ITEM(ti));
if (c->ln->items)
{
it = (Evas_Object_Textblock_Item *)(EINA_INLIST_GET(c->ln->items))->last;
int cutoff, len;
+ cutoff = 0;
len = eina_unicode_strlen(ti->text);
do
{
* no text nodes, make sure it's the case. */
if (ti->parent.text_node)
{
- cutoff = evas_common_script_end_of_run_get(
- eina_ustrbuf_string_get(ti->parent.text_node->unicode),
+ cutoff = evas_common_language_script_end_of_run_get(
+ ti->text,
ti->parent.text_node->bidi_props,
ti->parent.text_pos, len);
if (cutoff > 0)
{
new_ti = _layout_text_item_new(c, fmt, ti->text + cutoff);
_layout_item_text_cutoff(c, ti, cutoff);
+ new_ti->parent.text_node = ti->parent.text_node;
+ new_ti->parent.text_pos = ti->parent.text_pos + cutoff;
+ evas_common_text_props_bidi_set(&new_ti->parent.text_props,
+ new_ti->parent.text_node->bidi_props,
+ new_ti->parent.text_pos);
+ evas_common_text_props_script_set (&new_ti->parent.text_props,
+ new_ti->text);
+ /* FIXME: I possibly can use the alread calculated lengths */
+ c->ENFN->font_shape(c->ENDT, ti->format->font.font, ti->text,
+ &ti->parent.text_props,
+ ti->parent.text_node->bidi_props,
+ ti->parent.text_pos, cutoff);
+ c->ENFN->font_shape(c->ENDT, new_ti->format->font.font,
+ new_ti->text,
+ &new_ti->parent.text_props,
+ new_ti->parent.text_node->bidi_props,
+ new_ti->parent.text_pos, len - cutoff);
}
}
tw = th = 0;
if (fmt->font.font)
c->ENFN->font_string_size_get(c->ENDT, fmt->font.font, ti->text,
- &ti->parent.bidi_props, &tw, &th);
+ &ti->parent.text_props, &tw, &th);
ti->parent.w = tw;
ti->parent.h = th;
inset = 0;
adv = 0;
if (fmt->font.font)
adv = c->ENFN->font_h_advance_get(c->ENDT, fmt->font.font,
- ti->text, &ti->parent.bidi_props);
+ ti->text, &ti->parent.text_props);
ti->parent.adv = adv;
c->x += adv;
c->ln->items = (Evas_Object_Textblock_Item *)
if (cutoff > 0)
{
- new_ti->parent.text_node = ti->parent.text_node;
- new_ti->parent.text_pos = ti->parent.text_pos + cutoff;
-#ifdef BIDI_SUPPORT
- new_ti->parent.bidi_props.dir = (evas_bidi_is_rtl_char(
- new_ti->parent.text_node->bidi_props,
- new_ti->parent.text_pos,
- 0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
-#else
- new_ti->parent.bidi_props.dir = EVAS_BIDI_DIRECTION_LTR;
-#endif
ti = new_ti;
len -= cutoff;
}
alloc_str[off] = 0;
}
str = alloc_str;
-
- /* Shape the string */
-# ifdef BIDI_SUPPORT
- evas_bidi_shape_string(alloc_str, n->bidi_props, start, off);
-# endif
}
}
ti->parent.text_pos = start + str - tbase;
if (ti->parent.text_node)
{
-#ifdef BIDI_SUPPORT
- ti->parent.bidi_props.dir = (evas_bidi_is_rtl_char(
- ti->parent.text_node->bidi_props,
- ti->parent.text_pos,
- 0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
-#else
- ti->parent.bidi_props.dir = EVAS_BIDI_DIRECTION_LTR;
-#endif
+ evas_common_text_props_bidi_set(&ti->parent.text_props,
+ ti->parent.text_node->bidi_props, ti->parent.text_pos);
+ evas_common_text_props_script_set (&ti->parent.text_props,
+ ti->text);
+ c->ENFN->font_shape(c->ENDT, ti->format->font.font, ti->text,
+ &ti->parent.text_props, ti->parent.text_node->bidi_props,
+ ti->parent.text_pos, eina_unicode_strlen(ti->text));
}
tw = th = 0;
if (fmt->font.font)
c->ENFN->font_string_size_get(c->ENDT, fmt->font.font, ti->text,
- &ti->parent.bidi_props, &tw, &th);
+ &ti->parent.text_props, &tw, &th);
/* Check if we need to wrap, i.e the text is bigger than the width
* Only calculate wrapping if the width of the object is > 0 */
if ((c->w >= 0) &&
else
{
empty_item = 1;
- /* FIXME: use proper cleaning here */
- if (ti->text) free(ti->text);
- _format_unref_free(c->obj, ti->format);
- free(ti);
+ _item_free(c->obj, NULL, _ITEM(ti));
if (c->ln->items)
{
ti = _ITEM_TEXT((EINA_INLIST_GET(c->ln->items))->last);
fi->parent.text_node = n->text_node;
/* FIXME: make it more efficient */
fi->parent.text_pos = _evas_textblock_node_format_pos_get(n);
-#ifdef BIDI_SUPPORT
- fi->parent.bidi_props.dir = (evas_bidi_is_rtl_char(
- fi->parent.text_node->bidi_props,
- fi->parent.text_pos,
- 0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
-#else
- fi->parent.bidi_props.dir = EVAS_BIDI_DIRECTION_LTR;
-#endif
+ evas_common_text_props_bidi_set(&fi->parent.text_props,
+ fi->parent.text_node->bidi_props, fi->parent.text_pos);
}
return fi;
}
* @return line number of the char on success, -1 on error.
*/
static int
-_evas_textblock_cursor_char_pen_geometry_common_get(int (*query_func) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch), const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
+_evas_textblock_cursor_char_pen_geometry_common_get(int (*query_func) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch), const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
{
Evas_Object_Textblock *o;
Evas_Object_Textblock_Line *ln = NULL;
{
ret = query_func(cur->ENDT,
ti->format->font.font,
- ti->text, &ti->parent.bidi_props,
+ ti->text, &ti->parent.text_props,
pos,
&x, &y, &w, &h);
}
pos = cur->ENFN->font_char_at_coords_get(
cur->ENDT,
ti->format->font.font,
- ti->text, &ti->parent.bidi_props,
+ ti->text, &ti->parent.text_props,
x - it->x - ln->x, 0,
&cx, &cy, &cw, &ch);
if (pos < 0)
if ((start && !switch_items) || (!start && switch_items))
{
#ifdef BIDI_SUPPORT
- if (it->bidi_props.dir == EVAS_BIDI_DIRECTION_RTL)
+ if (it->text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
*w = *x + *w;
*x = 0;
else
{
#ifdef BIDI_SUPPORT
- if (it->bidi_props.dir == EVAS_BIDI_DIRECTION_RTL)
+ if (it->text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
*x = *x + *w;
*w = it->adv - *x;
ti = _ITEM_TEXT(it1);
ret = cur->ENFN->font_pen_coords_get(cur->ENDT,
ti->format->font.font,
- ti->text, &ti->parent.bidi_props,
+ ti->text, &ti->parent.text_props,
start,
&x1, &y, &w1, &h);
if (!ret)
}
ret = cur->ENFN->font_pen_coords_get(cur->ENDT,
ti->format->font.font,
- ti->text, &ti->parent.bidi_props,
+ ti->text, &ti->parent.text_props,
end,
&x2, &y, &w2, &h);
if (!ret)
}
#ifdef BIDI_SUPPORT
- if (ti->parent.bidi_props.dir == EVAS_BIDI_DIRECTION_RTL)
+ if (ti->parent.text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
x = x1 + w1;
w = x2 + w2 - x;
ret = cur->ENFN->font_pen_coords_get(cur->ENDT,
ti->format->font.font,
- ti->text, &ti->parent.bidi_props,
+ ti->text, &ti->parent.text_props,
start,
&x, &y, &w, &h);
if (!ret)
ret = cur->ENFN->font_pen_coords_get(cur->ENDT,
ti->format->font.font,
- ti->text, &ti->parent.bidi_props,
+ ti->text, &ti->parent.text_props,
end,
&x, &y, &w, &h);
if (!ret)
if (ti->format->font.font) ENFN->font_draw(output, context, surface, ti->format->font.font, \
obj->cur.geometry.x + ln->x + ti->parent.x + x + (ox), \
obj->cur.geometry.y + ln->y + yoff + y + (oy), \
- ti->parent.w, ti->parent.h, ti->parent.w, ti->parent.h, ti->text, &ti->parent.bidi_props);
+ ti->parent.w, ti->parent.h, ti->parent.w, ti->parent.h, ti->text, &ti->parent.text_props);
#define ITEM_WALK_LINE_SKIP_DROP() \
if ((ln->y + ln->h) <= 0) continue; \
if (ln->y > obj->cur.geometry.h) break
evas_regionbuf.c \
evas_pipe.c \
language/evas_bidi_utils.c \
-language/evas_script_utils.c \
+language/evas_language_utils.c \
+evas_text_utils.c \
+evas_font_ot.c \
evas_map_image.c \
evas_map_image.h
evas_scale_span.h \
evas_pipe.h \
language/evas_bidi_utils.h \
-language/evas_script_utils.h \
+language/evas_language_utils.h \
+evas_text_utils.h \
+evas_font_ot.h \
evas_map_image_internal.c \
evas_map_image_core.c \
evas_map_image_loop.c
#ifndef _EVAS_FONT_H
#define _EVAS_FONT_H
-#include "language/evas_bidi_utils.h"
+#include "evas_text_utils.h"
/* main */
/* draw */
-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 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_Text_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);
EAPI void evas_common_font_draw_init (void);
/* query */
EAPI int evas_common_font_query_kerning (RGBA_Font_Int* fi, FT_UInt left, FT_UInt right, int* kerning);
-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 void evas_common_font_query_size (RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_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_pen_coords (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, 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);
+EAPI void evas_common_font_query_advance (RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_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_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch);
+EAPI int evas_common_font_query_pen_coords (RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
+EAPI int evas_common_font_query_char_at_coords (RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_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_Text_Props *intl_props, int x, int y);
#ifdef EVAS_FRAME_QUEUING
EAPI void evas_common_font_draw_finish(void);
--- /dev/null
+#ifndef _EVAS_FONT_DEFAULT_WALK_X
+#define _EVAS_FONT_DEFAULT_WALK_X
+/* Macros for text walking */
+
+/**
+ * @def EVAS_FONT_UPDATE_KERN()
+ * @internal
+ * This macro updates pen_x and kern according to kerning.
+ * This macro assumes the following variables exist:
+ * intl_props, char_index, adv, fi, kern, pen_x
+ */
+#ifdef BIDI_SUPPORT
+#define EVAS_FONT_UPDATE_KERN(is_visual) \
+ do \
+ { \
+ /* 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 && (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && \
+ visible && !is_visual) \
+ { \
+ if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \
+ pen_x += kern; \
+ } \
+ else \
+ { \
+ if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \
+ pen_x += kern; \
+ } \
+ } \
+ while (0)
+#else
+#define EVAS_FONT_UPDATE_KERN(is_visual) \
+ do \
+ { \
+ (void) is_visual; \
+ if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \
+ pen_x += kern; \
+ } \
+ while (0)
+#endif
+
+/**
+ * @def EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
+ * @internal
+ * This runs through the variable text while updating char_index,
+ * which is the current index in the text. This macro exposes (inside
+ * the loop) the following vars:
+ * adv - advancement
+ * gl - the current unicode code point
+ * bear_x, bear_y, width - info about the bitmap
+ * pen_x, pen_y - (also available outside of the loop, but updated here)
+ * fg - the font glyph.
+ * index, prev_index - font indexes.
+ * Does not end with a ;
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_END
+ */
+#define EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() \
+ do \
+ { \
+ const Eina_Unicode *_base_text; \
+ int _char_index_d, _i; \
+ int visible; \
+ prev_index = 0; \
+ _base_text = text; \
+ for ( ; *text ; text++); \
+ _i = text - _base_text; \
+ if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
+ { \
+ char_index = text - _base_text - 1; \
+ text--; \
+ _char_index_d = -1; \
+ } \
+ else \
+ { \
+ char_index = 0; \
+ text = _base_text; \
+ _char_index_d = 1; \
+ } \
+ for ( ; _i > 0 ; char_index += _char_index_d, text += _char_index_d, _i--) \
+ { \
+ FT_UInt index; \
+ RGBA_Font_Glyph *fg; \
+ int gl, kern; \
+ gl = *text; \
+ if (gl == 0) break;
+/**
+ * @def EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START
+ * @internal
+ * FIXME: update
+ * This runs through the variable text while updating char_index,
+ * which is the current index in the text. This macro exposes (inside
+ * the loop) the following vars:
+ * adv - advancement
+ * gl - the current unicode code point
+ * bear_x, bear_y, width - info about the bitmap
+ * pen_x, pen_y - (also available outside of the loop, but updated here)
+ * fg - the font glyph.
+ * index, prev_index - font indexes.
+ * Does not end with a ;
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_END
+ */
+#define EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() \
+ do \
+ { \
+ int visible; \
+ prev_index = 0; \
+ for (char_index = 0 ; *text ; text++, char_index++) \
+ { \
+ FT_UInt index; \
+ RGBA_Font_Glyph *fg; \
+ int gl, kern; \
+ gl = *text; \
+ if (gl == 0) break;
+
+/*FIXME: doc */
+#define EVAS_FONT_WALK_DEFAULT_X_OFF (kern)
+#define EVAS_FONT_WALK_DEFAULT_Y_OFF (0)
+#define EVAS_FONT_WALK_DEFAULT_X_BEAR (fg->glyph_out->left)
+#define EVAS_FONT_WALK_DEFAULT_Y_BEAR (fg->glyph_out->top)
+#define EVAS_FONT_WALK_DEFAULT_X_ADV (fg->glyph->advance.x >> 16)
+#define EVAS_FONT_WALK_DEFAULT_Y_ADV (0)
+#define EVAS_FONT_WALK_DEFAULT_WIDTH (fg->glyph_out->bitmap.width)
+#define EVAS_FONT_WALK_DEFAULT_POS (char_index)
+#define EVAS_FONT_WALK_DEFAULT_IS_LAST \
+ (!text[char_index])
+#define EVAS_FONT_WALK_DEFAULT_IS_FIRST \
+ (!char_index)
+#define EVAS_FONT_WALK_DEFAULT_POS_NEXT \
+ ((!EVAS_FONT_WALK_DEFAULT_IS_LAST) ? \
+ (char_index + 1) : \
+ (char_index) \
+ )
+#define EVAS_FONT_WALK_DEFAULT_POS_PREV \
+ ((!EVAS_FONT_WALK_DEFAULT_IS_FIRST) ? \
+ (char_index - 1) : \
+ EVAS_FONT_WALK_DEFAULT_POS \
+ )
+#define EVAS_FONT_WALK_DEFAULT_LEN (EVAS_FONT_WALK_ORIG_LEN)
+/**
+ * @def EVAS_FONT_WALK_DEFAULT_TEXT_WORK
+ * @internal
+ * This macro actually updates the values mentioned in EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
+ * according to the current positing in the walk.
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_END
+ */
+#define EVAS_FONT_WALK_DEFAULT_TEXT_WORK(is_visual) \
+ 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; \
+ } \
+ kern = 0; \
+ if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl)) \
+ { \
+ visible = 0; \
+ } \
+ else \
+ { \
+ visible = 1; \
+ } \
+ /* 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)) \
+ { \
+ EVAS_FONT_UPDATE_KERN(is_visual); \
+ } \
+ \
+ pface = fi->src->ft.face; \
+ LKU(fi->ft_mutex); \
+
+/**
+ * @def EVAS_FONT_WALK_DEFAULT_TEXT_END
+ * @internal
+ * Closes EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START, needs to end with a ;
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK
+ */
+#define EVAS_FONT_WALK_DEFAULT_TEXT_END() \
+ if (visible) \
+ { \
+ pen_x += EVAS_FONT_WALK_DEFAULT_X_ADV; \
+ } \
+ prev_index = index; \
+ } \
+ } \
+ while(0)
+
+
+#endif
#include "language/evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */
#include "evas_font_private.h" /* for Frame-Queuing support */
+#include "evas_font_ot.h"
+
#define WORD_CACHE_MAXLEN 50
/* How many to cache */
#define WORD_CACHE_NWORDS 40
#if defined(METRIC_CACHE) || defined(WORD_CACHE)
LK(lock_words); // for word cache call
static Eina_Inlist *words = NULL;
-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);
+static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *text, Evas_Text_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning);
#endif
EAPI void
*/
static void
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,
+ const Evas_Text_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
)
{
struct prword *word;
word =
- evas_font_word_prerender(dc, text, (Evas_BiDi_Props *)intl_props,
+ evas_font_word_prerender(dc, text, (Evas_Text_Props *)intl_props,
len, fn, fi, use_kerning);
if (word)
{
}
#endif
-#ifdef BIDI_SUPPORT
- Eina_Unicode *visual_text = NULL;
-
- if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL))
- {
- visual_text = eina_unicode_strdup(in_text);
-
- if (visual_text)
- {
- evas_bidi_reverse_string(visual_text);
- text = visual_text;
- }
- }
- if (!visual_text)
- {
- text = in_text;
- }
-#else
- /*Suppress warnings */
- (void) intl_props;
-#endif
if (fi->src->current_size != fi->size)
{
FTLOCK();
fi->src->current_size = fi->size;
}
+
pen_x = x;
pen_y = y;
im = dst->image.data;
- EVAS_FONT_WALK_TEXT_START()
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
- int chr_x, chr_y, chr_w;
+ EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
+ {
+ int chr_x, chr_y, chr_w;
- if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl))
- continue;
+ if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl))
+ continue;
- EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE);
+ EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
- if (dc->font_ext.func.gl_new)
- {
- /* extension calls */
- 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 (dc->font_ext.func.gl_new)
+ {
+ /* extension calls */
+ fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
+ fg->ext_dat_free = dc->font_ext.func.gl_free;
+ }
- chr_x = (pen_x) + bear_x;
- chr_y = (pen_y) + bear_y;
- chr_w = width;
+ chr_x = (pen_x) + EVAS_FONT_WALK_OT_X_OFF + EVAS_FONT_WALK_OT_X_BEAR;
+ chr_y = (pen_y) + EVAS_FONT_WALK_OT_Y_OFF + EVAS_FONT_WALK_OT_Y_BEAR;
+ chr_w = EVAS_FONT_WALK_OT_WIDTH;
- if (chr_x < (ext_x + ext_w))
- {
- DATA8 *data;
- int i, j, w, h;
-
- data = fg->glyph_out->bitmap.buffer;
- j = fg->glyph_out->bitmap.pitch;
- w = fg->glyph_out->bitmap.width;
- if (j < w) j = w;
- h = fg->glyph_out->bitmap.rows;
- /*
- if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
- && (fg->glyph_out->bitmap.num_grays == 256)
- )
- */
+ if (chr_x < (ext_x + ext_w))
{
- if ((j > 0) && (chr_x + w > ext_x))
+ DATA8 *data;
+ int i, j, w, h;
+
+ data = fg->glyph_out->bitmap.buffer;
+ j = fg->glyph_out->bitmap.pitch;
+ w = fg->glyph_out->bitmap.width;
+ if (j < w) j = w;
+ h = fg->glyph_out->bitmap.rows;
+ /*
+ if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
+ && (fg->glyph_out->bitmap.num_grays == 256)
+ )
+ */
{
- if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
+ if ((j > 0) && (chr_x + w > ext_x))
{
- /* ext glyph draw */
- dc->font_ext.func.gl_draw(dc->font_ext.data,
- (void *)dst,
- dc, fg, chr_x,
- y - (chr_y - y));
- }
- else
- {
- if ((fg->glyph_out->bitmap.num_grays == 256) &&
- (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
+ if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
{
- for (i = 0; i < h; i++)
+ /* ext glyph draw */
+ dc->font_ext.func.gl_draw(dc->font_ext.data,
+ (void *)dst,
+ dc, fg, chr_x,
+ y - (chr_y - y));
+ }
+ else
+ {
+ if ((fg->glyph_out->bitmap.num_grays == 256) &&
+ (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
{
- int dx, dy;
- int in_x, in_w;
+ for (i = 0; i < h; i++)
+ {
+ int dx, dy;
+ int in_x, in_w;
- in_x = 0;
- in_w = 0;
- dx = chr_x;
- dy = y - (chr_y - i - y);
+ in_x = 0;
+ in_w = 0;
+ dx = chr_x;
+ dy = y - (chr_y - i - y);
#ifdef EVAS_SLI
- if (((dy) % dc->sli.h) == dc->sli.y)
+ if (((dy) % dc->sli.h) == dc->sli.y)
#endif
+ {
+ if ((dx < (ext_x + ext_w)) &&
+ (dy >= (ext_y)) &&
+ (dy < (ext_y + ext_h)))
+ {
+ if (dx + w > (ext_x + ext_w))
+ in_w += (dx + w) - (ext_x + ext_w);
+ if (dx < ext_x)
+ {
+ in_w += ext_x - dx;
+ in_x = ext_x - dx;
+ dx = ext_x;
+ }
+ if (in_w < w)
+ {
+ func(NULL, data + (i * j) + in_x, dc->col.col,
+ im + (dy * im_w) + dx, w - in_w);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ DATA8 *tmpbuf = NULL, *dp, *tp, bits;
+ int bi, bj;
+ const DATA8 bitrepl[2] = {0x0, 0xff};
+
+ tmpbuf = alloca(w);
+ for (i = 0; i < h; i++)
{
- if ((dx < (ext_x + ext_w)) &&
- (dy >= (ext_y)) &&
- (dy < (ext_y + ext_h)))
+ int dx, dy;
+ int in_x, in_w, end;
+
+ in_x = 0;
+ in_w = 0;
+ dx = chr_x;
+ dy = y - (chr_y - i - y);
+#ifdef EVAS_SLI
+ if (((dy) % dc->sli.h) == dc->sli.y)
+#endif
{
- if (dx + w > (ext_x + ext_w))
- in_w += (dx + w) - (ext_x + ext_w);
- if (dx < ext_x)
+ tp = tmpbuf;
+ dp = data + (i * fg->glyph_out->bitmap.pitch);
+ for (bi = 0; bi < w; bi += 8)
{
- in_w += ext_x - dx;
- in_x = ext_x - dx;
- dx = ext_x;
+ bits = *dp;
+ if ((w - bi) < 8) end = w - bi;
+ else end = 8;
+ for (bj = 0; bj < end; bj++)
+ {
+ *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
+ tp++;
+ }
+ dp++;
}
- if (in_w < w)
+ if ((dx < (ext_x + ext_w)) &&
+ (dy >= (ext_y)) &&
+ (dy < (ext_y + ext_h)))
{
- func(NULL, data + (i * j) + in_x, dc->col.col,
- im + (dy * im_w) + dx, w - in_w);
+ if (dx + w > (ext_x + ext_w))
+ in_w += (dx + w) - (ext_x + ext_w);
+ if (dx < ext_x)
+ {
+ in_w += ext_x - dx;
+ in_x = ext_x - dx;
+ dx = ext_x;
+ }
+ if (in_w < w)
+ {
+ func(NULL, tmpbuf + in_x, dc->col.col,
+ im + (dy * im_w) + dx, w - in_w);
+ }
}
}
}
}
}
+ }
+ }
+ }
+ else
+ break;
+ }
+ EVAS_FONT_WALK_OT_TEXT_END();
+ }
+ else
+#endif
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
+ {
+ int chr_x, chr_y, chr_w;
+
+ if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl))
+ continue;
+
+ EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
+
+ if (dc->font_ext.func.gl_new)
+ {
+ /* extension calls */
+ fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
+ fg->ext_dat_free = dc->font_ext.func.gl_free;
+ }
+
+ chr_x = (pen_x) + EVAS_FONT_WALK_DEFAULT_X_OFF + EVAS_FONT_WALK_DEFAULT_X_BEAR;
+ chr_y = (pen_y) + EVAS_FONT_WALK_DEFAULT_Y_OFF + EVAS_FONT_WALK_DEFAULT_Y_BEAR;
+ chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH;
+
+ if (chr_x < (ext_x + ext_w))
+ {
+ DATA8 *data;
+ int i, j, w, h;
+
+ data = fg->glyph_out->bitmap.buffer;
+ j = fg->glyph_out->bitmap.pitch;
+ w = fg->glyph_out->bitmap.width;
+ if (j < w) j = w;
+ h = fg->glyph_out->bitmap.rows;
+ /*
+ if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
+ && (fg->glyph_out->bitmap.num_grays == 256)
+ )
+ */
+ {
+ if ((j > 0) && (chr_x + w > ext_x))
+ {
+ if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
+ {
+ /* ext glyph draw */
+ dc->font_ext.func.gl_draw(dc->font_ext.data,
+ (void *)dst,
+ dc, fg, chr_x,
+ y - (chr_y - y));
+ }
else
{
- DATA8 *tmpbuf = NULL, *dp, *tp, bits;
- int bi, bj;
- const DATA8 bitrepl[2] = {0x0, 0xff};
-
- tmpbuf = alloca(w);
- for (i = 0; i < h; i++)
+ if ((fg->glyph_out->bitmap.num_grays == 256) &&
+ (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
{
- int dx, dy;
- int in_x, in_w, end;
+ for (i = 0; i < h; i++)
+ {
+ int dx, dy;
+ int in_x, in_w;
- in_x = 0;
- in_w = 0;
- dx = chr_x;
- dy = y - (chr_y - i - y);
+ in_x = 0;
+ in_w = 0;
+ dx = chr_x;
+ dy = y - (chr_y - i - y);
#ifdef EVAS_SLI
- if (((dy) % dc->sli.h) == dc->sli.y)
+ if (((dy) % dc->sli.h) == dc->sli.y)
#endif
- {
- tp = tmpbuf;
- dp = data + (i * fg->glyph_out->bitmap.pitch);
- for (bi = 0; bi < w; bi += 8)
{
- bits = *dp;
- if ((w - bi) < 8) end = w - bi;
- else end = 8;
- for (bj = 0; bj < end; bj++)
+ if ((dx < (ext_x + ext_w)) &&
+ (dy >= (ext_y)) &&
+ (dy < (ext_y + ext_h)))
{
- *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
- tp++;
+ if (dx + w > (ext_x + ext_w))
+ in_w += (dx + w) - (ext_x + ext_w);
+ if (dx < ext_x)
+ {
+ in_w += ext_x - dx;
+ in_x = ext_x - dx;
+ dx = ext_x;
+ }
+ if (in_w < w)
+ {
+ func(NULL, data + (i * j) + in_x, dc->col.col,
+ im + (dy * im_w) + dx, w - in_w);
+ }
}
- dp++;
}
- if ((dx < (ext_x + ext_w)) &&
- (dy >= (ext_y)) &&
- (dy < (ext_y + ext_h)))
+ }
+ }
+ else
+ {
+ DATA8 *tmpbuf = NULL, *dp, *tp, bits;
+ int bi, bj;
+ const DATA8 bitrepl[2] = {0x0, 0xff};
+
+ tmpbuf = alloca(w);
+ for (i = 0; i < h; i++)
+ {
+ int dx, dy;
+ int in_x, in_w, end;
+
+ in_x = 0;
+ in_w = 0;
+ dx = chr_x;
+ dy = y - (chr_y - i - y);
+#ifdef EVAS_SLI
+ if (((dy) % dc->sli.h) == dc->sli.y)
+#endif
{
- if (dx + w > (ext_x + ext_w))
- in_w += (dx + w) - (ext_x + ext_w);
- if (dx < ext_x)
+ tp = tmpbuf;
+ dp = data + (i * fg->glyph_out->bitmap.pitch);
+ for (bi = 0; bi < w; bi += 8)
{
- in_w += ext_x - dx;
- in_x = ext_x - dx;
- dx = ext_x;
+ bits = *dp;
+ if ((w - bi) < 8) end = w - bi;
+ else end = 8;
+ for (bj = 0; bj < end; bj++)
+ {
+ *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
+ tp++;
+ }
+ dp++;
}
- if (in_w < w)
+ if ((dx < (ext_x + ext_w)) &&
+ (dy >= (ext_y)) &&
+ (dy < (ext_y + ext_h)))
{
- func(NULL, tmpbuf + in_x, dc->col.col,
- im + (dy * im_w) + dx, w - in_w);
+ if (dx + w > (ext_x + ext_w))
+ in_w += (dx + w) - (ext_x + ext_w);
+ if (dx < ext_x)
+ {
+ in_w += ext_x - dx;
+ in_x = ext_x - dx;
+ dx = ext_x;
+ }
+ if (in_w < w)
+ {
+ func(NULL, tmpbuf + in_x, dc->col.col,
+ im + (dy * im_w) + dx, w - in_w);
+ }
}
}
}
}
}
}
+ else
+ break;
}
- else
- break;
+ EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
- EVAS_FONT_WALK_TEXT_END();
-#ifdef BIDI_SUPPORT
- if (visual_text) free(visual_text);
-#endif
evas_common_font_int_use_trim();
}
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)
+ const Evas_Text_Props *intl_props)
{
int ext_x, ext_y, ext_w, ext_h;
int im_w, im_h;
/* Only used if cache is on */
#if defined(METRIC_CACHE) || defined(WORD_CACHE)
struct prword *
-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)
+evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Evas_Text_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning)
{
int pen_x, pen_y;
struct cinfo *metrics;
LK(lock_font_draw); // for freetype2 API calls
LK(lock_bidi); // for evas bidi internal usage.
+LK(lock_ot); // for evas bidi internal usage.
EAPI void
evas_common_font_init(void)
evas_common_font_draw_init();
LKI(lock_font_draw);
LKI(lock_bidi);
+ LKI(lock_ot);
}
EAPI void
LKD(lock_font_draw);
LKD(lock_bidi);
+ LKD(lock_ot);
evas_common_font_load_shutdown();
evas_common_font_cache_set(0);
--- /dev/null
+#include "evas_font_ot.h"
+
+#ifdef OT_SUPPORT
+# include <hb.h>
+# include <hb-ft.h>
+#endif
+
+#include "evas_common.h"
+
+#include <Eina.h>
+#include "evas_font_private.h"
+
+EAPI Eina_Bool
+evas_common_font_ot_is_enabled(void)
+{
+#ifdef OT_SUPPORT
+ static int ret = -1;
+ const char *env;
+ if (ret != -1)
+ {
+ return ret;
+ }
+
+ env = getenv("EVAS_USE_OT");
+ if (env && atoi(env))
+ {
+ ret = EINA_TRUE;
+ return ret;
+ }
+#endif
+ return EINA_FALSE;
+}
+
+
+#ifdef OT_SUPPORT
+static void
+_evas_common_font_ot_shape(hb_buffer_t *buffer, FT_Face face)
+{
+ hb_face_t *hb_face;
+ hb_font_t *hb_font;
+
+ hb_face = hb_ft_face_create(face, NULL);
+ hb_font = hb_ft_font_create(face, NULL);
+
+ hb_shape(hb_font, hb_face, buffer, NULL, 0);
+ hb_font_destroy(hb_font);
+ hb_face_destroy(hb_face);
+}
+
+EAPI Eina_Bool
+evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
+ Evas_Text_Props *props, int len)
+{
+ RGBA_Font *fn = (RGBA_Font *) _fn;
+ RGBA_Font_Int *fi;
+ hb_buffer_t *buffer;
+ hb_glyph_position_t *positions;
+ hb_glyph_info_t *infos;
+ int slen;
+ unsigned int i;
+ if (!evas_common_font_ot_is_enabled()) return EINA_TRUE;
+ if (props->ot_data)
+ {
+ evas_common_font_ot_props_unref(props->ot_data);
+ }
+ props->ot_data = calloc(1, sizeof(Evas_Font_OT_Data));
+ props->ot_data->refcount = 1;
+
+ fi = fn->fonts->data;
+ if (fi->src->current_size != fi->size)
+ {
+ FTLOCK();
+ FT_Activate_Size(fi->ft.size);
+ FTUNLOCK();
+ fi->src->current_size = fi->size;
+ }
+ /* Load the font needed for this script */
+ evas_common_font_glyph_search(fn, &fi, *text);
+
+ if (len < 0)
+ {
+ slen = eina_unicode_strlen(text);
+ }
+ else
+ {
+ slen = len;
+ }
+
+ buffer = hb_buffer_create(slen);
+ hb_buffer_set_unicode_funcs(buffer, evas_common_language_unicode_funcs_get());
+ hb_buffer_set_language(buffer, hb_language_from_string(
+ evas_common_language_from_locale_get()));
+ hb_buffer_set_script(buffer, props->script);
+ hb_buffer_set_direction(buffer,
+ (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ?
+ HB_DIRECTION_RTL : HB_DIRECTION_LTR);
+ /* FIXME: add run-time conversions if needed, which is very unlikely */
+ hb_buffer_add_utf32(buffer, (const uint32_t *) text, slen, 0, slen);
+
+ _evas_common_font_ot_shape(buffer, fi->src->ft.face);
+
+ props->ot_data->len = hb_buffer_get_length(buffer);
+ props->ot_data->items = calloc(props->ot_data->len,
+ sizeof(Evas_Font_OT_Data_Item));
+ positions = hb_buffer_get_glyph_positions(buffer);
+ infos = hb_buffer_get_glyph_infos(buffer);
+ for (i = 0 ; i < props->ot_data->len ; i++)
+ {
+ props->ot_data->items[i].index = infos[i].codepoint;
+ props->ot_data->items[i].source_pos = infos[i].cluster;
+ props->ot_data->items[i].x_advance = positions[i].x_advance;
+ props->ot_data->items[i].x_offset = positions[i].x_offset;
+ props->ot_data->items[i].y_offset = positions[i].y_offset;
+ }
+
+ hb_buffer_destroy(buffer);
+
+ return EINA_FALSE;
+}
+
+EAPI void
+evas_common_font_ot_props_ref(Evas_Font_OT_Data *data)
+{
+ data->refcount++;
+}
+
+EAPI void
+evas_common_font_ot_props_unref(Evas_Font_OT_Data *data)
+{
+ OTLOCK();
+ if (--data->refcount == 0)
+ {
+ if (data->items)
+ free(data->items);
+ free(data);
+ }
+ OTUNLOCK();
+}
+#endif
+
--- /dev/null
+#ifndef _EVAS_FONT_OT_H
+# define _EVAS_FONT_OT_H
+
+# ifdef HAVE_CONFIG_H
+# include "config.h"
+# endif
+
+# ifdef HAVE_HARFBUZZ
+# define OT_SUPPORT
+# define USE_HARFBUZZ
+# endif
+
+# ifdef OT_SUPPORT
+#include <stdlib.h>
+typedef struct _Evas_Font_OT_Data Evas_Font_OT_Data;
+typedef struct _Evas_Font_OT_Data_Item Evas_Font_OT_Data_Item;
+struct _Evas_Font_OT_Data
+{
+ int refcount;
+ size_t len;
+ Evas_Font_OT_Data_Item *items;
+};
+#endif
+
+#include "Evas.h"
+
+#ifdef OT_SUPPORT
+struct _Evas_Font_OT_Data_Item
+{
+ unsigned int index; /* Should conform to FT */
+ size_t source_pos;
+ Evas_Coord x_offset;
+ Evas_Coord y_offset;
+ Evas_Coord x_advance;
+};
+# else
+typedef void *Evas_Font_OT_Data;
+# endif
+
+# ifdef OT_SUPPORT
+# define EVAS_FONT_OT_X_OFF_GET(a) ((a).x_offset)
+# define EVAS_FONT_OT_Y_OFF_GET(a) ((a).y_offset)
+# define EVAS_FONT_OT_X_ADV_GET(a) ((a).x_advance)
+//# define EVAS_FONT_OT_Y_ADV_GET(a) ((a).y_advance)
+# define EVAS_FONT_OT_INDEX_GET(a) ((a).index)
+# define EVAS_FONT_OT_POS_GET(a) ((a).source_pos)
+#else
+# define EVAS_FONT_OT_X_OFF_GET(a) (0)
+# define EVAS_FONT_OT_Y_OFF_GET(a) (0)
+# define EVAS_FONT_OT_X_ADV_GET(a) (0)
+//# define EVAS_FONT_OT_POS_Y_ADV_GET(a) (0)
+# define EVAS_FONT_OT_INDEX_GET(a) (0) /* FIXME!!! */
+# define EVAS_FONT_OT_POS_GET(a) (0) /* FIXME!!! */
+# endif
+
+EAPI Eina_Bool
+evas_common_font_ot_is_enabled(void);
+
+EAPI void
+evas_common_font_ot_props_ref(Evas_Font_OT_Data *data);
+
+EAPI void
+evas_common_font_ot_props_unref(Evas_Font_OT_Data *data);
+
+#include "evas_text_utils.h"
+EAPI Eina_Bool
+evas_common_font_ot_populate_text_props(void *fn, const Eina_Unicode *text,
+ Evas_Text_Props *props, int len);
+#endif
+
--- /dev/null
+#ifndef _EVAS_FONT_OT_WALK_X
+#define _EVAS_FONT_OT_WALK_X
+# include "evas_font_ot.h"
+# include "language/evas_language_utils.h"
+
+/* Macros for text walking */
+
+/**
+ * @def EVAS_FONT_WALK_OT_TEXT_VISUAL_START
+ * @internal
+ * This runs through the variable text while updating char_index,
+ * which is the current index in the text. This macro exposes (inside
+ * the loop) the following vars:
+ * adv - advancement
+ * gl - the current unicode code point
+ * bear_x, bear_y, width - info about the bitmap
+ * pen_x, pen_y - (also available outside of the loop, but updated here)
+ * fg - the font glyph.
+ * index, prev_index - font indexes.
+ * Does not end with a ;
+ * @see EVAS_FONT_WALK_OT_TEXT_INIT
+ * @see EVAS_FONT_WALK_OT_TEXT_WORK
+ * @see EVAS_FONT_WALK_OT_TEXT_END
+ */
+#define EVAS_FONT_WALK_OT_TEXT_VISUAL_START() \
+ do \
+ { \
+ int visible; \
+ prev_index = 0; \
+ /* Load the glyph according to the first letter of the script, preety
+ * bad, but will have to do */ \
+ evas_common_font_glyph_search(fn, &fi, *text); \
+ for (char_index = 0 ; char_index < intl_props->ot_data->len ; char_index++) \
+ { \
+ FT_UInt index; \
+ RGBA_Font_Glyph *fg; \
+ int gl, kern; \
+ gl = 0; /* FIXME: hack */
+/**
+ * @def EVAS_FONT_WALK_OT_TEXT_LOGICAL_START
+ * @internal
+ * FIXME: not up to date
+ * This runs through the variable text while updating char_index,
+ * which is the current index in the text. This macro exposes (inside
+ * the loop) the following vars:
+ * adv - advancement
+ * gl - the current unicode code point
+ * bear_x, bear_y, width - info about the bitmap
+ * pen_x, pen_y - (also available outside of the loop, but updated here)
+ * fg - the font glyph.
+ * index, prev_index - font indexes.
+ * Does not end with a ;
+ * @see EVAS_FONT_WALK_OT_TEXT_INIT
+ * @see EVAS_FONT_WALK_OT_TEXT_WORK
+ * @see EVAS_FONT_WALK_OT_TEXT_END
+ */
+#define EVAS_FONT_WALK_OT_TEXT_LOGICAL_START() \
+ do \
+ { \
+ int _char_index_d, _i; \
+ int visible; \
+ /* Load the glyph according to the first letter of the script, preety
+ * bad, but will have to do */ \
+ evas_common_font_glyph_search(fn, &fi, *text); \
+ prev_index = 0; \
+ _i = intl_props->ot_data->len; \
+ if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
+ { \
+ char_index = intl_props->ot_data->len - 1; \
+ _char_index_d = -1; \
+ } \
+ else \
+ { \
+ char_index = 0; \
+ _char_index_d = 1; \
+ } \
+ for ( ; _i > 0 ; char_index += _char_index_d, _i--) \
+ { \
+ FT_UInt index; \
+ RGBA_Font_Glyph *fg; \
+ int gl, kern; \
+ gl = 0; /* FIXME: hack */
+
+/*FIXME: doc */
+#define EVAS_FONT_WALK_OT_X_OFF \
+ (EVAS_FONT_OT_X_OFF_GET( \
+ intl_props->ot_data->items[char_index]) >> 6)
+#define EVAS_FONT_WALK_OT_Y_OFF \
+ (EVAS_FONT_OT_Y_OFF_GET( \
+ intl_props->ot_data->items[char_index]) >> 6)
+#define EVAS_FONT_WALK_OT_X_BEAR (fg->glyph_out->left)
+#define EVAS_FONT_WALK_OT_Y_BEAR (fg->glyph_out->top)
+#define EVAS_FONT_WALK_OT_X_ADV \
+ (EVAS_FONT_OT_X_ADV_GET( \
+ intl_props->ot_data->items[char_index]) >> 6)
+#define EVAS_FONT_WALK_OT_WIDTH (fg->glyph_out->bitmap.width)
+#define EVAS_FONT_WALK_OT_POS \
+ (EVAS_FONT_OT_POS_GET( \
+ intl_props->ot_data->items[char_index]))
+#define EVAS_FONT_WALK_OT_IS_LAST \
+ (char_index + 1 == intl_props->ot_data->len)
+#define EVAS_FONT_WALK_OT_IS_FIRST \
+ (!char_index)
+#define EVAS_FONT_WALK_OT_POS_NEXT \
+ ((!EVAS_FONT_WALK_OT_IS_LAST) ? \
+ EVAS_FONT_OT_POS_GET( \
+ intl_props->ot_data->items[char_index + 1]) : \
+ EVAS_FONT_WALK_OT_POS \
+ )
+#define EVAS_FONT_WALK_OT_POS_PREV \
+ ((char_index > 0) ? \
+ EVAS_FONT_OT_POS_GET( \
+ intl_props->ot_data->items[char_index - 1]) : \
+ EVAS_FONT_WALK_OT_POS \
+ )
+#define EVAS_FONT_WALK_OT_LEN (intl_props->ot_data->len)
+/**
+ * @def EVAS_FONT_WALK_OT_TEXT_WORK
+ * @internal
+ * This macro actually updates the values mentioned in EVAS_FONT_WALK_OT_TEXT_VISUAL_START
+ * according to the current positing in the walk.
+ * @see EVAS_FONT_WALK_OT_TEXT_VISUAL_START
+ * @see EVAS_FONT_WALK_OT_TEXT_INIT
+ * @see EVAS_FONT_WALK_OT_TEXT_END
+ */
+#define EVAS_FONT_WALK_OT_TEXT_WORK(is_visual) \
+ index = EVAS_FONT_OT_INDEX_GET(intl_props->ot_data->items[char_index]); \
+ LKL(fi->ft_mutex); \
+ fg = evas_common_font_int_cache_glyph_get(fi, index); \
+ if (!fg) \
+ { \
+ LKU(fi->ft_mutex); \
+ continue; \
+ } \
+ kern = 0; \
+ if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl)) \
+ { \
+ visible = 0; \
+ } \
+ else \
+ { \
+ visible = 1; \
+ } \
+ \
+ pface = fi->src->ft.face; \
+ LKU(fi->ft_mutex);
+
+/**
+ * @def EVAS_FONT_WALK_OT_TEXT_END
+ * @internal
+ * Closes EVAS_FONT_WALK_OT_TEXT_VISUAL_START, needs to end with a ;
+ * @see EVAS_FONT_WALK_OT_TEXT_VISUAL_START
+ * @see EVAS_FONT_WALK_OT_TEXT_INIT
+ * @see EVAS_FONT_WALK_OT_TEXT_WORK
+ */
+#define EVAS_FONT_WALK_OT_TEXT_END() \
+ if (visible) \
+ { \
+ pen_x += EVAS_FONT_WALK_OT_X_ADV; \
+ } \
+ prev_index = index; \
+ } \
+ /* FIXME: clean up */ \
+ } \
+ while(0)
+
+
+#endif
#ifndef _EVAS_FONT_PRIVATE_H
# define _EVAS_FONT_PRIVATE_H
+#include "evas_font_ot.h"
#ifdef BUILD_PTHREAD
extern LK(lock_font_draw); // for freetype2 API calls
extern LK(lock_bidi); // for fribidi API calls
+extern LK(lock_ot); // for harfbuzz calls
#endif
# if defined(EVAS_FRAME_QUEUING) || defined(BUILD_PIPE_RENDER)
# define BIDILOCK() LKL(lock_bidi)
# define BIDIUNLOCK() LKU(lock_bidi)
+
+# define OTLOCK() LKL(lock_ot)
+# define OTUNLOCK() LKU(lock_ot)
# else
# define FTLOCK(x)
# define FTUNLOCK(x)
# define BIDILOCK()
# define BIDIUNLOCK()
-# endif
void evas_common_font_source_unload(RGBA_Font_Source *fs);
void evas_common_font_source_reload(RGBA_Font_Source *fs);
void evas_common_font_int_unload(RGBA_Font_Int *fi);
void evas_common_font_int_reload(RGBA_Font_Int *fi);
/* Macros for text walking */
+# define OTLOCK()
+# define OTUNLOCK()
+# endif
-#define EVAS_FONT_CHARACTER_IS_INVISIBLE(x) ( \
+# define EVAS_FONT_CHARACTER_IS_INVISIBLE(x) ( \
((0x200C <= (x)) && ((x) <= 0x200D)) || /* ZWNJ..ZWH */ \
((0x200E <= (x)) && ((x) <= 0x200F)) || /* BIDI stuff */ \
((0x202A <= (x)) && ((x) <= 0x202E)) /* BIDI stuff */ \
)
-/**
- * @def EVAS_FONT_UPDATE_KERN()
- * @internal
- * This macro updates pen_x and kern according to kerning.
- * This macro assumes the following variables exist:
- * intl_props, char_index, adv, fi, kern, pen_x
- */
-#ifdef BIDI_SUPPORT
-#define EVAS_FONT_UPDATE_KERN(is_visual) \
- do \
- { \
- /* 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 && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL) && \
- visible && !is_visual) \
- { \
- if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \
- pen_x += kern; \
- } \
- else \
- { \
- if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \
- pen_x += kern; \
- } \
- } \
- while (0)
-#else
-#define EVAS_FONT_UPDATE_KERN(is_visual) \
- do \
- { \
- (void) is_visual; \
- if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \
- pen_x += kern; \
- } \
- while (0)
-#endif
+# define EVAS_FONT_WALK_ORIG_LEN (_len)
+
+# ifdef OT_SUPPORT
+# include "evas_font_ot_walk.x"
+# endif
+
+# include "evas_font_default_walk.x"
/**
* @def EVAS_FONT_WALK_TEXT_INIT
* @see EVAS_FONT_WALK_TEXT_WORK
* @see EVAS_FONT_WALK_TEXT_END
*/
-#define EVAS_FONT_WALK_TEXT_INIT() \
+# define EVAS_FONT_WALK_TEXT_INIT() \
int pen_x = 0, pen_y = 0; \
- int char_index; \
+ size_t char_index; \
FT_UInt prev_index; \
FT_Face pface = NULL; \
+ int _len = eina_unicode_strlen(text); \
+ (void) _len; /* We don't have to use it */ \
(void) pen_y; /* Sometimes it won't be used */
+<<<<<<< HEAD
/**
* @def EVAS_FONT_WALK_TEXT_START
* @internal
} \
while(0)
+=======
+>>>>>>> Evas: Multiple changes that all relate to the Harfbuzz integration:
#endif /* !_EVAS_FONT_PRIVATE_H */
}
/* text x inset */
+/* FIXME: should use OT info when available. */
EAPI int
evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text)
{
*/
EAPI void
-evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props __UNUSED__, int *w, int *h)
+evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props __UNUSED__, int *w, int *h)
{
int keep_width = 0;
int prev_pen_x = 0;
EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
- EVAS_FONT_WALK_TEXT_START()
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
- EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
- /* Keep the width because we'll need it for the last char */
- keep_width = width + bear_x;
- /* Keep the previous pen_x, before it's advanced in TEXT_END */
- prev_pen_x = pen_x;
+ EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
+ {
+ EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
+ if (!visible) continue;
+ /* Keep the width because we'll need it for the last char */
+ keep_width = EVAS_FONT_WALK_OT_WIDTH + EVAS_FONT_WALK_OT_X_OFF +
+ EVAS_FONT_WALK_OT_X_BEAR;
+ /* Keep the previous pen_x, before it's advanced in TEXT_END */
+ prev_pen_x = pen_x;
+ }
+ EVAS_FONT_WALK_OT_TEXT_END();
+ }
+ else
+#endif
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
+ if (!visible) continue;
+ /* Keep the width because we'll need it for the last char */
+ keep_width = EVAS_FONT_WALK_DEFAULT_WIDTH +
+ EVAS_FONT_WALK_DEFAULT_X_OFF +
+ EVAS_FONT_WALK_DEFAULT_X_BEAR;
+ /* Keep the previous pen_x, before it's advanced in TEXT_END */
+ prev_pen_x = pen_x;
+ }
+ EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
- EVAS_FONT_WALK_TEXT_END();
if (w) *w = prev_pen_x + keep_width;
if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn);
evas_common_font_int_use_trim();
* this way, we are safe.
*/
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)
+evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *h_adv, int *v_adv)
{
int use_kerning;
RGBA_Font_Int *fi;
(void) intl_props;
#endif
- EVAS_FONT_WALK_TEXT_START()
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
+ {
+ EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
+ {
+ EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
+ if (!visible) continue;
+ }
+ EVAS_FONT_WALK_OT_TEXT_END();
+ }
+ else
+#endif
{
- EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
+ EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
+ if (!visible) continue;
+ }
+ EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
- EVAS_FONT_WALK_TEXT_END();
if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
if (h_adv) *h_adv = pen_x;
*/
EAPI int
-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)
+evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
{
int asc, desc;
int position = 0;
EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
-#ifdef BIDI_SUPPORT
- Eina_Unicode *visual_text = NULL;
- int len;
-
- if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL))
- {
- visual_text = eina_unicode_strdup(in_text);
-
- if (visual_text)
- {
- evas_bidi_reverse_string(visual_text);
- text = visual_text;
- }
- }
- if (!visual_text)
- {
- text = in_text;
- }
- len = eina_unicode_strlen(text);
-#endif
-
asc = evas_common_font_max_ascent_get(fn);
desc = evas_common_font_max_descent_get(fn);
-#ifdef BIDI_SUPPORT
- /* Get the position in the visual string because those are the coords we care about */
- position = evas_bidi_position_reverse(intl_props, len, pos);
-#else
position = pos;
-#endif
/* If it's the null, choose location according to the direction. */
if (!text[position])
{
/* if it's rtl then the location is the left of the string,
* otherwise, the right. */
#ifdef BIDI_SUPPORT
- if (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)
+ if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
if (cx) *cx = 0;
if (ch) *ch = asc + desc;
goto end;
}
- EVAS_FONT_WALK_TEXT_START()
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
- int chr_x, chr_y, chr_w;
-
- EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE);
-
- chr_x = (pen_x) + bear_x;
- chr_y = (pen_y) + bear_y;
- chr_w = width;
- /* 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;
- }
+ EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
+ {
+ int chr_x, chr_w;
+ int found = 0, items = 1, item_pos = 1;
+
+ EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
+ if (visible)
+ {
+ chr_x = (pen_x) + EVAS_FONT_WALK_OT_X_OFF +
+ EVAS_FONT_WALK_OT_X_BEAR;
+ chr_w = EVAS_FONT_WALK_OT_WIDTH;
+ }
+ else
+ {
+ chr_x = pen_x;
+ chr_w = 0;
+ }
+ /* we need to see if the char at the visual position is the char wanted */
+ if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
+ (EVAS_FONT_WALK_OT_POS <= (size_t) position) &&
+ ((((size_t) position) < EVAS_FONT_WALK_OT_POS_NEXT) ||
+ (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_NEXT)))
+ {
+ found = 1;
+ items = EVAS_FONT_WALK_OT_POS_NEXT - EVAS_FONT_WALK_OT_POS;
+ if (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_NEXT)
+ {
+ /* If there was only one char, take the original lens
+ * for the number of items. */
+ items = EVAS_FONT_WALK_ORIG_LEN -
+ EVAS_FONT_WALK_OT_POS;
+ }
+ item_pos = position - EVAS_FONT_WALK_OT_POS + 1;
+ }
+ else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
+ ((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) ||
+ (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_PREV)) &&
+ (((size_t) position) >= EVAS_FONT_WALK_OT_POS))
+ {
+ found = 1;
+ items = EVAS_FONT_WALK_OT_POS_PREV - EVAS_FONT_WALK_OT_POS;
+ if (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_PREV)
+ {
+ /* If there was only one char, take the original lens
+ * for the number of items. */
+ items = EVAS_FONT_WALK_ORIG_LEN -
+ EVAS_FONT_WALK_OT_POS;
+ }
+ item_pos = items - (position - EVAS_FONT_WALK_OT_POS);
+ }
+
+ if (found)
+ {
+ if (cx) *cx = chr_x +
+ (EVAS_FONT_WALK_OT_WIDTH / items) * (item_pos - 1);
+ if (cy) *cy = -asc;
+ if (cw) *cw = chr_w / items;
+ if (ch) *ch = asc + desc;
+ ret_val = 1;
+ goto end;
+ }
+ }
+ EVAS_FONT_WALK_OT_TEXT_END();
}
- EVAS_FONT_WALK_TEXT_END();
-end:
-
-#ifdef BIDI_SUPPORT
- if (visual_text) free(visual_text);
+ else
#endif
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
+ {
+ int chr_x, chr_w;
+
+ EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
+ if (visible)
+ {
+ chr_x = (pen_x) + EVAS_FONT_WALK_DEFAULT_X_OFF +
+ EVAS_FONT_WALK_DEFAULT_X_BEAR;
+ chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH;
+ }
+ else
+ {
+ chr_x = pen_x;
+ chr_w = 0;
+ }
+ /* we need to see if the char at the visual position is the char wanted */
+ if (EVAS_FONT_WALK_DEFAULT_POS == (size_t) position)
+ {
+ if (cx) *cx = chr_x + EVAS_FONT_WALK_DEFAULT_WIDTH;
+ if (cy) *cy = -asc;
+ if (cw) *cw = chr_w;
+ if (ch) *ch = asc + desc;
+ ret_val = 1;
+ goto end;
+ }
+ }
+ EVAS_FONT_WALK_DEFAULT_TEXT_END();
+ }
+end:
evas_common_font_int_use_trim();
return ret_val;
*/
EAPI int
-evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
+evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
{
int asc, desc;
int position = 0;
EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
-#ifdef BIDI_SUPPORT
- Eina_Unicode *visual_text = NULL;
- int len;
-
- if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL))
- {
- visual_text = eina_unicode_strdup(in_text);
-
- if (visual_text)
- {
- evas_bidi_reverse_string(visual_text);
- text = visual_text;
- }
- }
- if (!visual_text)
- {
- text = in_text;
- }
- len = eina_unicode_strlen(text);
-#endif
-
asc = evas_common_font_max_ascent_get(fn);
desc = evas_common_font_max_descent_get(fn);
-#ifdef BIDI_SUPPORT
- /* Get the position in the visual string because those are the coords we care about */
- position = evas_bidi_position_reverse(intl_props, len, pos);
-#else
position = pos;
-#endif
/* If it's the null, choose location according to the direction. */
if (!text[position])
{
/* if it's rtl then the location is the left of the string,
* otherwise, the right. */
#ifdef BIDI_SUPPORT
- if (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)
+ if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
if (cpen_x) *cpen_x = 0;
if (ch) *ch = asc + desc;
ret_val = 1;
goto end;
}
-
- EVAS_FONT_WALK_TEXT_START()
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
- EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE);
- /* we need to see if the char at the visual position is the char wanted */
- if (char_index == position)
- {
- if (cpen_x) *cpen_x = pen_x;
- if (cy) *cy = -asc;
- if (cadv) *cadv = adv;
- if (ch) *ch = asc + desc;
- ret_val = 1;
- goto end;
- }
+ EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
+ {
+ int found = 0, items = 1, item_pos = 1;
+ EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
+ /* we need to see if the char at the visual position is the char wanted */
+ if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
+ (EVAS_FONT_WALK_OT_POS <= (size_t) position) &&
+ ((((size_t) position) < EVAS_FONT_WALK_OT_POS_NEXT) ||
+ (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_NEXT)))
+ {
+ found = 1;
+ items = EVAS_FONT_WALK_OT_POS_NEXT - EVAS_FONT_WALK_OT_POS;
+ if (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_NEXT)
+ {
+ /* If there was only one char, take the original lens
+ * for the number of items. */
+ items = EVAS_FONT_WALK_ORIG_LEN -
+ EVAS_FONT_WALK_OT_POS;
+ }
+ item_pos = position - EVAS_FONT_WALK_OT_POS + 1;
+ }
+ else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
+ ((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) ||
+ (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_PREV)) &&
+ (((size_t) position) >= EVAS_FONT_WALK_OT_POS))
+ {
+ found = 1;
+ items = EVAS_FONT_WALK_OT_POS_PREV - EVAS_FONT_WALK_OT_POS;
+ if (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_PREV)
+ {
+ /* If there was only one char, take the original lens
+ * for the number of items. */
+ items = EVAS_FONT_WALK_ORIG_LEN -
+ EVAS_FONT_WALK_OT_POS;
+ }
+ item_pos = items - (position - EVAS_FONT_WALK_OT_POS);
+ }
+
+ if (found)
+ {
+ if (cy) *cy = -asc;
+ if (ch) *ch = asc + desc;
+ /* FIXME: A hack to make combining chars work nice, should
+ * change to take the base char's adv. */
+ if (visible)
+ {
+ if (EVAS_FONT_WALK_OT_X_ADV > 0)
+ {
+ if (cpen_x) *cpen_x = pen_x +
+ (EVAS_FONT_WALK_OT_X_ADV / items) *
+ (item_pos - 1);
+ if (cadv) *cadv = (EVAS_FONT_WALK_OT_X_ADV / items);
+ }
+ else
+ {
+ if (cpen_x) *cpen_x = pen_x +
+ EVAS_FONT_WALK_OT_X_OFF +
+ EVAS_FONT_WALK_OT_X_BEAR +
+ (EVAS_FONT_WALK_OT_WIDTH / items) *
+ (item_pos - 1);
+ if (cadv) *cadv = (EVAS_FONT_WALK_OT_WIDTH / items);
+ }
+ }
+ else
+ {
+ if (cpen_x) *cpen_x = pen_x;
+ if (cadv) *cadv = 0;
+ }
+ ret_val = 1;
+ goto end;
+ }
+ }
+ EVAS_FONT_WALK_OT_TEXT_END();
}
- EVAS_FONT_WALK_TEXT_END();
-end:
-
-#ifdef BIDI_SUPPORT
- if (visual_text) free(visual_text);
+ else
#endif
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
+
+ if ((EVAS_FONT_WALK_DEFAULT_POS == (size_t) position))
+ {
+ if (cy) *cy = -asc;
+ if (ch) *ch = asc + desc;
+ /* FIXME: A hack to make combining chars work nice, should change
+ * to take the base char's adv. */
+ if (visible)
+ {
+ if (EVAS_FONT_WALK_DEFAULT_X_ADV > 0)
+ {
+ if (cpen_x) *cpen_x = pen_x +
+ EVAS_FONT_WALK_DEFAULT_X_ADV;
+ if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_X_ADV;
+ }
+ else
+ {
+ if (cpen_x) *cpen_x = pen_x +
+ EVAS_FONT_WALK_DEFAULT_X_OFF +
+ EVAS_FONT_WALK_DEFAULT_X_BEAR +
+ EVAS_FONT_WALK_DEFAULT_WIDTH;
+ if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_WIDTH;
+ }
+ }
+ else
+ {
+ if (cpen_x) *cpen_x = pen_x;
+ if (cadv) *cadv = 0;
+ }
+ ret_val = 1;
+ goto end;
+ }
+ }
+ EVAS_FONT_WALK_DEFAULT_TEXT_END();
+ }
+end:
return ret_val;
}
*/
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)
+evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
{
int asc, desc;
const Eina_Unicode *text = in_text;
(void) intl_props;
#endif
-#ifdef BIDI_SUPPORT
- Eina_Unicode *visual_text = NULL;
- int len;
-
- if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL))
+ asc = evas_common_font_max_ascent_get(fn);
+ desc = evas_common_font_max_descent_get(fn);
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
- visual_text = eina_unicode_strdup(in_text);
-
- if (visual_text)
+ EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
{
- evas_bidi_reverse_string(visual_text);
- text = visual_text;
+ EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
+ if (!visible) continue;
+
+ /* we need to see if the char at the visual position is the char,
+ * we check that by checking if it's before the current pen
+ * position and the next */
+ if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_OT_X_ADV)) &&
+ (y >= -asc) && (y <= desc))
+ {
+ int items = 1, item_pos = 1;
+
+ if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR)
+ {
+ double part;
+ items = EVAS_FONT_WALK_OT_POS_NEXT -
+ EVAS_FONT_WALK_OT_POS;
+ /* If it's the last/first char in a ltr/rtl string */
+ if (items == 0)
+ {
+ items = EVAS_FONT_WALK_ORIG_LEN -
+ EVAS_FONT_WALK_OT_POS;
+ }
+ part = EVAS_FONT_WALK_OT_X_ADV / items;
+ item_pos = (int) ((x - pen_x) / part);
+ }
+ else
+ {
+ double part;
+ items = EVAS_FONT_WALK_OT_POS_PREV -
+ EVAS_FONT_WALK_OT_POS;
+ /* If it's the last/first char in a ltr/rtl string */
+ if (items == 0)
+ {
+ items = EVAS_FONT_WALK_ORIG_LEN -
+ EVAS_FONT_WALK_OT_POS;
+ }
+ part = EVAS_FONT_WALK_OT_X_ADV / items;
+ item_pos = items - ((int) ((x - pen_x) / part)) - 1;
+ }
+ if (cx) *cx = pen_x + EVAS_FONT_WALK_OT_X_OFF +
+ EVAS_FONT_WALK_OT_X_BEAR +
+ ((EVAS_FONT_WALK_OT_X_ADV / items) * (item_pos - 1));
+ if (cy) *cy = -asc;
+ if (cw) *cw = (EVAS_FONT_WALK_OT_X_ADV / items);
+ if (ch) *ch = asc + desc;
+ ret_val = EVAS_FONT_WALK_OT_POS + item_pos;
+ goto end;
+ }
}
+ EVAS_FONT_WALK_OT_TEXT_END();
}
- if (!visual_text)
- {
- text = in_text;
- }
- len = eina_unicode_strlen(text);
+ else
#endif
-
- asc = evas_common_font_max_ascent_get(fn);
- desc = evas_common_font_max_descent_get(fn);
-
- EVAS_FONT_WALK_TEXT_START()
{
- int chr_x, chr_w;
-
- EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE);
-
- chr_x = (pen_x) + bear_x;
- chr_w = width;
- /* we need to see if the char at the visual position is the char,
- * we check that by checking if it's before the current pen position
- * and the next */
- if ((x >= pen_x) && (x <= (pen_x + adv)) &&
- (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 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_reverse(intl_props, len, position);
-#endif
- ret_val = position;
- goto end;
- }
+ EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
+ if (!visible) continue;
+
+ /* we need to see if the char at the visual position is the char,
+ * we check that by checking if it's before the current pen position
+ * and the next */
+ if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_DEFAULT_X_ADV))
+ && (y >= -asc) && (y <= desc))
+ {
+ if (cx) *cx = pen_x + EVAS_FONT_WALK_DEFAULT_X_OFF +
+ EVAS_FONT_WALK_DEFAULT_X_BEAR +
+ EVAS_FONT_WALK_DEFAULT_X_ADV;
+ if (cy) *cy = -asc;
+ if (cw) *cw = EVAS_FONT_WALK_DEFAULT_X_ADV;
+ if (ch) *ch = asc + desc;
+ ret_val = EVAS_FONT_WALK_DEFAULT_POS;
+ goto end;
+ }
+ }
+ EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
- EVAS_FONT_WALK_TEXT_END();
end:
-#ifdef BIDI_SUPPORT
- if (visual_text) free(visual_text);
-#endif
evas_common_font_int_use_trim();
return ret_val;
*/
EAPI int
-evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props __UNUSED__, int x, int y)
+evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props __UNUSED__, int x, int y)
{
int asc, desc;
int ret=-1;
asc = evas_common_font_max_ascent_get(fn);
desc = evas_common_font_max_descent_get(fn);
- EVAS_FONT_WALK_TEXT_START()
+
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
+ {
+ EVAS_FONT_WALK_OT_TEXT_LOGICAL_START()
+ {
+ EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
+ if (!visible) continue;
+
+ if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_OT_X_ADV)) &&
+ (y >= -asc) && (y <= desc))
+ {
+ ret = EVAS_FONT_WALK_OT_POS;
+ goto end;
+ }
+ }
+ EVAS_FONT_WALK_OT_TEXT_END();
+ }
+ else
+#endif
{
- EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
-
- if ((x >= pen_x) && (x <= (pen_x + adv)) &&
- (y >= -asc) && (y <= desc))
- {
- ret = char_index;
- goto end;
- }
+ EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
+ {
+ EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
+ if (!visible) continue;
+
+ if ((x >= pen_x) &&
+ (x <= (pen_x + EVAS_FONT_WALK_DEFAULT_X_ADV)) &&
+ (y >= -asc) && (y <= desc))
+ {
+ ret = char_index;
+ goto end;
+ }
+ }
+ EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
- EVAS_FONT_WALK_TEXT_END();
end:
evas_common_font_int_use_trim();
return ret;
}
+
#else
evas_common_font_free(op->op.text.font);
#endif
-#ifdef BIDI_SUPPORT
- evas_bidi_props_clean(&(op->op.text.intl_props));
-#endif
+ evas_common_text_props_content_unref(&(op->op.text.intl_props));
free(op->op.text.text);
evas_common_pipe_op_free(op);
}
EAPI void
evas_common_pipe_text_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)
+ RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
{
RGBA_Pipe_Op *op;
op->op.text.x = x;
op->op.text.y = y;
op->op.text.text = eina_unicode_strdup(text);
-#ifdef BIDI_SUPPORT
- evas_bidi_props_copy_and_ref(intl_props, &(op->op.text.intl_props));
-#endif
+ evas_common_text_props_content_copy_and_ref(intl_props,
+ &(op->op.text.intl_props));
#ifdef EVAS_FRAME_QUEUING
LKL(fn->ref_fq_add);
fn->ref_fq[0]++;
EAPI void evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
EAPI void evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1);
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_text_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 void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_Text_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_begin(RGBA_Image *root);
--- /dev/null
+#include "evas_text_utils.h"
+#include "language/evas_bidi_utils.h"
+#include "language/evas_language_utils.h"
+#include "evas_font_ot.h"
+
+void
+evas_common_text_props_bidi_set(Evas_Text_Props *props,
+ Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start)
+{
+#ifdef BIDI_SUPPORT
+ props->bidi.dir = (evas_bidi_is_rtl_char(
+ bidi_par_props,
+ 0,
+ start)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
+#else
+ (void) start;
+ (void) bidi_par_props;
+ props->bidi.dir = EVAS_BIDI_DIRECTION_LTR;
+#endif
+}
+
+void
+evas_common_text_props_script_set(Evas_Text_Props *props,
+ const Eina_Unicode *str)
+{
+ props->script = evas_common_language_script_type_get(str);
+}
+
+void
+evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
+ const Evas_Text_Props *src)
+{
+ memcpy(dst, src, sizeof(Evas_Text_Props));
+#ifdef OT_SUPPORT
+ if (dst->ot_data)
+ {
+ evas_common_font_ot_props_ref(dst->ot_data);
+ }
+#endif
+}
+
+void
+evas_common_text_props_content_unref(Evas_Text_Props *props)
+{
+#ifdef OT_SUPPORT
+ if (props->ot_data)
+ {
+ evas_common_font_ot_props_unref(props->ot_data);
+ }
+#else
+ (void) props;
+#endif
+#ifdef BIDI_SUPPORT
+ evas_bidi_props_clean(&props->bidi);
+#else
+ (void) props;
+#endif
+}
+
--- /dev/null
+#ifndef _EVAS_TEXT_UTILS_H
+# define _EVAS_TEXT_UTILS_H
+
+typedef struct _Evas_Text_Props Evas_Text_Props;
+
+# include "evas_font_ot.h"
+# include "language/evas_bidi_utils.h"
+# include "language/evas_language_utils.h"
+
+struct _Evas_Text_Props
+{
+ Evas_BiDi_Props bidi;
+ Evas_Script_Type script;
+ Evas_Font_OT_Data *ot_data;
+};
+
+void
+evas_common_text_props_bidi_set(Evas_Text_Props *props,
+ Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start);
+
+void
+evas_common_text_props_script_set(Evas_Text_Props *props,
+ const Eina_Unicode *str);
+
+void
+evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
+ const Evas_Text_Props *src);
+
+void
+evas_common_text_props_content_unref(Evas_Text_Props *props);
+
+#endif
#endif
};
-#include "evas_common.h"
-struct _Evas_BiDi_Props {
+#include "Evas.h"
+struct _Evas_BiDi_Props
+{
Evas_BiDi_Direction dir;
};
--- /dev/null
+/**
+ * @internal
+ * @addtogroup Evas_Utils
+ *
+ * @{
+ */
+/**
+ * @internal
+ * @defgroup Evas_Script Evas Script (language) utility functions
+ *
+ * This set of functions and types helps evas handle scripts correctly.
+ * @todo Document types, structures and macros.
+ *
+ * @{
+ */
+#include <Eina.h>
+
+#include "evas_language_utils.h"
+#include "evas_bidi_utils.h" /* Used for fallback. */
+#include "../evas_font_ot.h" /* Used for harfbuzz info */
+
+#ifdef USE_HARFBUZZ
+# include <hb.h>
+# ifdef HAVE_HARFBUZZ_GLIB
+# include <hb-glib.h>
+# endif
+#endif
+
+/* FIXME: rename and move */
+void *
+evas_common_language_unicode_funcs_get(void)
+{
+#if defined(USE_HARFBUZZ) && defined(HAVE_HARFBUZZ_GLIB)
+ return hb_glib_get_unicode_funcs();
+#endif
+ return NULL;
+}
+
+static Evas_Script_Type
+_get_script(Eina_Unicode unicode)
+{
+#ifdef USE_HARFBUZZ
+ static hb_unicode_funcs_t *funcs;
+ if (!funcs)
+ funcs = evas_common_language_unicode_funcs_get();
+ return hb_unicode_get_script(funcs, unicode);
+#else
+ (void) unicode;
+#endif
+ return EVAS_SCRIPT_COMMON;
+}
+
+int
+evas_common_language_script_end_of_run_get(const Eina_Unicode *str,
+ const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len)
+{
+ /* FIXME: Use the standard segmentation instead */
+ if (evas_common_font_ot_is_enabled())
+ {
+ Evas_Script_Type first = EVAS_SCRIPT_UNKNOWN;
+ int i;
+ for (i = 0 ; (i < len) ; i++, str++)
+ {
+ Evas_Script_Type tmp;
+ tmp = _get_script(*str);
+ /* Arabic is the first script in the array that's not
+ * common/inherited. */
+ if ((first == EVAS_SCRIPT_UNKNOWN) && (tmp >= EVAS_SCRIPT_ARABIC))
+ {
+ first = tmp;
+ continue;
+ }
+ if ((first != tmp) && (tmp >= EVAS_SCRIPT_ARABIC))
+ {
+ break;
+ }
+ }
+#ifdef BIDI_SUPPORT
+ {
+ int bidi_end;
+ bidi_end = evas_bidi_end_of_run_get(bidi_props, start, len);
+ if (bidi_end > 0)
+ {
+ i = (i < bidi_end) ? i : bidi_end;
+ }
+ }
+#else
+ (void) bidi_props;
+ (void) start;
+#endif
+ return (i < len) ? i : 0;
+ }
+ else
+ {
+#ifdef BIDI_SUPPORT
+ return evas_bidi_end_of_run_get(bidi_props, start, len);
+#endif
+ }
+ return 0;
+}
+
+Evas_Script_Type
+evas_common_language_script_type_get(const Eina_Unicode *str)
+{
+ Evas_Script_Type script = EVAS_SCRIPT_COMMON;
+ /* Arabic is the first script in the array that's not a common/inherited */
+ for ( ; *str && ((script = _get_script(*str)) < EVAS_SCRIPT_ARABIC) ; str++)
+ ;
+ return script;
+}
+
+const char *
+evas_common_language_from_locale_get(void)
+{
+ static char lang[6]; /* FIXME: Maximum length I know about */
+ if (*lang) return lang;
+
+ const char *locale;
+ locale = getenv("LANG");
+ if (locale && *locale)
+ {
+ char *itr;
+ strncpy(lang, locale, 5);
+ lang[5] = '\0';
+ itr = lang;
+ while (*itr)
+ {
+ if (*itr == '_')
+ {
+ *itr = '\0';
+ }
+ itr++;
+ }
+ return lang;
+ }
+
+ return "";
+}
+
+/*
+ * @}
+ */
+/*
+ * @}
+ */
+
--- /dev/null
+#ifndef _EVAS_LANGUAGE_UTILS
+#define _EVAS_LANGUAGE_UTILS
+
+#include <Eina.h>
+#include "evas_bidi_utils.h"
+
+/* Unicode Script property - conforming to HARFBUZZ's */
+typedef enum
+{
+ EVAS_SCRIPT_INVALID_CODE = -1,
+ EVAS_SCRIPT_COMMON = 0, /* Zyyy */
+ EVAS_SCRIPT_INHERITED, /* Qaai */
+ EVAS_SCRIPT_ARABIC, /* Arab */
+ EVAS_SCRIPT_ARMENIAN, /* Armn */
+ EVAS_SCRIPT_BENGALI, /* Beng */
+ EVAS_SCRIPT_BOPOMOFO, /* Bopo */
+ EVAS_SCRIPT_CHEROKEE, /* Cher */
+ EVAS_SCRIPT_COPTIC, /* Qaac */
+ EVAS_SCRIPT_CYRILLIC, /* Cyrl (Cyrs) */
+ EVAS_SCRIPT_DESERET, /* Dsrt */
+ EVAS_SCRIPT_DEVANAGARI, /* Deva */
+ EVAS_SCRIPT_ETHIOPIC, /* Ethi */
+ EVAS_SCRIPT_GEORGIAN, /* Geor (Geon, Geoa) */
+ EVAS_SCRIPT_GOTHIC, /* Goth */
+ EVAS_SCRIPT_GREEK, /* Grek */
+ EVAS_SCRIPT_GUJARATI, /* Gujr */
+ EVAS_SCRIPT_GURMUKHI, /* Guru */
+ EVAS_SCRIPT_HAN, /* Hani */
+ EVAS_SCRIPT_HANGUL, /* Hang */
+ EVAS_SCRIPT_HEBREW, /* Hebr */
+ EVAS_SCRIPT_HIRAGANA, /* Hira */
+ EVAS_SCRIPT_KANNADA, /* Knda */
+ EVAS_SCRIPT_KATAKANA, /* Kana */
+ EVAS_SCRIPT_KHMER, /* Khmr */
+ EVAS_SCRIPT_LAO, /* Laoo */
+ EVAS_SCRIPT_LATIN, /* Latn (Latf, Latg) */
+ EVAS_SCRIPT_MALAYALAM, /* Mlym */
+ EVAS_SCRIPT_MONGOLIAN, /* Mong */
+ EVAS_SCRIPT_MYANMAR, /* Mymr */
+ EVAS_SCRIPT_OGHAM, /* Ogam */
+ EVAS_SCRIPT_OLD_ITALIC, /* Ital */
+ EVAS_SCRIPT_ORIYA, /* Orya */
+ EVAS_SCRIPT_RUNIC, /* Runr */
+ EVAS_SCRIPT_SINHALA, /* Sinh */
+ EVAS_SCRIPT_SYRIAC, /* Syrc (Syrj, Syrn, Syre) */
+ EVAS_SCRIPT_TAMIL, /* Taml */
+ EVAS_SCRIPT_TELUGU, /* Telu */
+ EVAS_SCRIPT_THAANA, /* Thaa */
+ EVAS_SCRIPT_THAI, /* Thai */
+ EVAS_SCRIPT_TIBETAN, /* Tibt */
+ EVAS_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */
+ EVAS_SCRIPT_YI, /* Yiii */
+ EVAS_SCRIPT_TAGALOG, /* Tglg */
+ EVAS_SCRIPT_HANUNOO, /* Hano */
+ EVAS_SCRIPT_BUHID, /* Buhd */
+ EVAS_SCRIPT_TAGBANWA, /* Tagb */
+
+ /* Unicode-4.0 additions */
+ EVAS_SCRIPT_BRAILLE, /* Brai */
+ EVAS_SCRIPT_CYPRIOT, /* Cprt */
+ EVAS_SCRIPT_LIMBU, /* Limb */
+ EVAS_SCRIPT_OSMANYA, /* Osma */
+ EVAS_SCRIPT_SHAVIAN, /* Shaw */
+ EVAS_SCRIPT_LINEAR_B, /* Linb */
+ EVAS_SCRIPT_TAI_LE, /* Tale */
+ EVAS_SCRIPT_UGARITIC, /* Ugar */
+
+ /* Unicode-4.1 additions */
+ EVAS_SCRIPT_NEW_TAI_LUE, /* Talu */
+ EVAS_SCRIPT_BUGINESE, /* Bugi */
+ EVAS_SCRIPT_GLAGOLITIC, /* Glag */
+ EVAS_SCRIPT_TIFINAGH, /* Tfng */
+ EVAS_SCRIPT_SYLOTI_NAGRI, /* Sylo */
+ EVAS_SCRIPT_OLD_PERSIAN, /* Xpeo */
+ EVAS_SCRIPT_KHAROSHTHI, /* Khar */
+
+ /* Unicode-5.0 additions */
+ EVAS_SCRIPT_UNKNOWN, /* Zzzz */
+ EVAS_SCRIPT_BALINESE, /* Bali */
+ EVAS_SCRIPT_CUNEIFORM, /* Xsux */
+ EVAS_SCRIPT_PHOENICIAN, /* Phnx */
+ EVAS_SCRIPT_PHAGS_PA, /* Phag */
+ EVAS_SCRIPT_NKO, /* Nkoo */
+
+ /* Unicode-5.1 additions */
+ EVAS_SCRIPT_KAYAH_LI, /* Kali */
+ EVAS_SCRIPT_LEPCHA, /* Lepc */
+ EVAS_SCRIPT_REJANG, /* Rjng */
+ EVAS_SCRIPT_SUNDANESE, /* Sund */
+ EVAS_SCRIPT_SAURASHTRA, /* Saur */
+ EVAS_SCRIPT_CHAM, /* Cham */
+ EVAS_SCRIPT_OL_CHIKI, /* Olck */
+ EVAS_SCRIPT_VAI, /* Vaii */
+ EVAS_SCRIPT_CARIAN, /* Cari */
+ EVAS_SCRIPT_LYCIAN, /* Lyci */
+ EVAS_SCRIPT_LYDIAN, /* Lydi */
+
+ /* Unicode-5.2 additions */
+ EVAS_SCRIPT_AVESTAN, /* Avst */
+ EVAS_SCRIPT_BAMUM, /* Bamu */
+ EVAS_SCRIPT_EGYPTIAN_HIEROGLYPHS, /* Egyp */
+ EVAS_SCRIPT_IMPERIAL_ARAMAIC, /* Armi */
+ EVAS_SCRIPT_INSCRIPTIONAL_PAHLAVI, /* Phli */
+ EVAS_SCRIPT_INSCRIPTIONAL_PARTHIAN, /* Prti */
+ EVAS_SCRIPT_JAVANESE, /* Java */
+ EVAS_SCRIPT_KAITHI, /* Kthi */
+ EVAS_SCRIPT_LISU, /* Lisu */
+ EVAS_SCRIPT_MEITEI_MAYEK, /* Mtei */
+ EVAS_SCRIPT_OLD_SOUTH_ARABIAN, /* Sarb */
+ EVAS_SCRIPT_OLD_TURKIC, /* Orkh */
+ EVAS_SCRIPT_SAMARITAN, /* Samr */
+ EVAS_SCRIPT_TAI_THAM, /* Lana */
+ EVAS_SCRIPT_TAI_VIET /* Tavt */
+} Evas_Script_Type;
+
+int
+evas_common_language_script_end_of_run_get(const Eina_Unicode *str, const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len);
+
+Evas_Script_Type
+evas_common_language_script_type_get(const Eina_Unicode *str);
+
+const char *
+evas_common_language_from_locale_get(void);
+
+void *
+evas_common_language_unicode_funcs_get(void);
+#endif
+
+++ /dev/null
-/**
- * @internal
- * @addtogroup Evas_Utils
- *
- * @{
- */
-/**
- * @internal
- * @defgroup Evas_Script Evas Script (language) utility functions
- *
- * This set of functions and types helps evas handle scripts correctly.
- * @todo Document types, structures and macros.
- *
- * @{
- */
-#include <Eina.h>
-
-#include "evas_script_utils.h"
-#include "evas_bidi_utils.h" /* Used for fallback. */
-int
-evas_common_script_end_of_run_get(const Eina_Unicode *str,
- const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len)
-{
- /* FIXME: Currently we fall back to bidi runs, should fix */
- (void) str;
-#ifdef BIDI_SUPPORT
- return evas_bidi_end_of_run_get(bidi_props, start, len);
-#else
- (void) bidi_props;
- (void) start;
- (void) len;
- return 0;
-#endif
-}
-
-/*
- * @}
- */
-/*
- * @}
- */
-
+++ /dev/null
-#ifndef _EVAS_SCRIPT_UTILS
-#define _EVAS_SCRIPT_UTILS
-
-#include <Eina.h>
-#include "evas_bidi_utils.h"
-
-int
-evas_common_script_end_of_run_get(const Eina_Unicode *str, const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len);
-
-#endif
-
#ifdef BUILD_PIPE_RENDER
#include "../engines/common/evas_map_image.h"
-#include "../engines/common/language/evas_bidi_utils.h"
+#include "../engines/common/evas_text_utils.h"
struct _RGBA_Pipe_Op
{
RGBA_Font *font;
int x, y;
Eina_Unicode *text;
- Evas_BiDi_Props intl_props;
+ Evas_Text_Props intl_props;
} text;
struct {
RGBA_Image *src;
#include "../file/evas_module.h"
#include "../file/evas_path.h"
+#include "../engines/common/evas_text_utils.h"
#include "../engines/common/language/evas_bidi_utils.h"
-#include "../engines/common/language/evas_script_utils.h"
+#include "../engines/common/language/evas_language_utils.h"
#ifdef EVAS_MAGIC_DEBUG
/* complain when peole pass in wrong object types etc. */
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h);
+ void (*font_string_size_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_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);
+ int (*font_h_advance_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props);
+ int (*font_v_advance_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props);
+ int (*font_char_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_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_Text_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_Text_Props *intl_props);
void (*font_cache_flush) (void *data);
void (*font_cache_set) (void *data, int bytes);
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y);
+ int (*font_last_up_to_pos) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_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);
void (*image_content_hint_set) (void *data, void *surface, int hint);
int (*image_content_hint_get) (void *data, void *surface);
- int (*font_pen_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
+ int (*font_pen_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
+ Eina_Bool (*font_shape) (void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len);
};
struct _Evas_Image_Load_Func
static int eng_font_v_advance_get(void *data, void *font, char *text);
static int eng_font_char_coords_get(void *data, void *font, char *text, int pos, int *cx, int *cy, int *cw, int *ch);
static int eng_font_pen_coords_get(void *data, void *font, char *text, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
+static Eina_Bool eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len);
static int eng_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch);
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, char *text);
static void eng_font_cache_flush(void *data);
NULL, // ORD(image_map_surface_free);
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
- eng_font_pen_coords_get
+ eng_font_pen_coords_get,
+ eng_font_shape
/* FUTURE software generic calls go here */
};
return 0;
}
+
+static Eina_Bool
+eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
+{
+ Render_Engine *re;
+
+ /* FIXME, use cairo font subsystem */
+ re = (Render_Engine *)data;
+ return EINA_TRUE;
+}
+
static int
eng_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch)
{
}
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
Render_Engine *re = (Render_Engine *)data;
RGBA_Image im;
* 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
DirectFB_Engine_Image_Entry *eim = surface;
IDirectFBSurface *screen;
}
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
Render_Engine *re;
}
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
Render_Engine *re;
}
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
Render_Engine *re;
}
static void
-eng_font_string_size_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int *w, int *h)
+eng_font_string_size_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int *w, int *h)
{
Render_Engine *re = (Render_Engine *)data;
Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font;
}
static int
-eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props)
+eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props)
{
int w;
}
static int
-eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props)
+eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props)
{
int h;
}
static int
-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)
+eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
{
Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font;
/*FIXME: this is *NOT* implemennted correctly, look at the other engines to
* see what needed to be done */
static int
-eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
+eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
{
return eng_font_char_coords_get(data, font, text, intl_props, pos, cpen_x,
cy, cadv, ch)
}
+static Eina_Bool
+eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props __UNUSED__, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
+{
+#ifdef BIDI_SUPPORT
+ return !evas_bidi_shape_string(text, par_props, pos, len);
+#endif
+ return EINA_TRUE;
+}
+
static int
-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)
+eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_Text_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;
}
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, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
Render_Engine *re = (Render_Engine *)data;
Evas_Quartz_Context *ctxt = (Evas_Quartz_Context *)context;
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, const Evas_BiDi_Props *intl_props, int *w, int *h);
+static void eng_font_string_size_get(void *data, void *font, const char *text, const Evas_Text_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, const Evas_BiDi_Props *intl_props);
-static int eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props);
-static int 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);
-static int eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
-static int 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);
-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, const Evas_BiDi_Props *intl_props);
+static int eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props);
+static int eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props);
+static int eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch);
+static int eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
+static Eina_Bool eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len);
+static int eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch);
+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, const Evas_Text_Props *intl_props);
static void eng_font_hinting_set(void *data, void *font, int hinting);
static int eng_font_hinting_can_hint(void *data, int hinting);
}
static void
-eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h)
+eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h)
{
evas_common_font_query_size(font, text, intl_props, w, h);
}
}
static int
-eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
{
int h, v;
}
static int
-eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
{
int h, v;
}
static int
-eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
+eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
{
return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen_x, cy, cadv, ch);
}
+static Eina_Bool
+eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
+{
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled())
+ {
+ return evas_common_font_ot_populate_text_props(font, text,
+ intl_props, len);
+ }
+ else
+#endif
+ {
+#ifdef BIDI_SUPPORT
+ return !evas_bidi_shape_string(text, par_props, pos, len);
+#endif
+ }
+ return EINA_TRUE;
+}
+
static int
-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)
+eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props, 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_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y)
+eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
static RGBA_Image *im = NULL;
Soft16_Image *dst = surface;
NULL, // ORD(image_map_surface_free);
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
- eng_font_pen_coords_get
+ eng_font_pen_coords_get,
+ eng_font_shape
/* FUTURE software generic calls go here */
};
}
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
static RGBA_Image *im = NULL;
SDL_Engine_Image_Entry *eim = surface;
}
static void
-eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props,
+eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
int *w, int *h)
{
evas_common_font_query_size(font, text, intl_props, w, h);
}
static int
-eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
{
int h, v;
}
static int
-eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
{
int h, v;
}
static int
-eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props,
+eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
int pos, int *cpen, int *cy, int *cadv, int *ch)
{
return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen, cy, cadv, ch);
}
+static Eina_Bool
+eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
+{
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled())
+ {
+ return evas_common_font_ot_populate_text_props(font, text,
+ intl_props, len);
+ }
+ else
+#endif
+ {
+#ifdef BIDI_SUPPORT
+ return !evas_bidi_shape_string(text, par_props, pos, len);
+#endif
+ }
+ return EINA_TRUE;
+}
+
static int
-eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props,
+eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
int pos, int *cx, int *cy, int *cw, int *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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props,
+eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
int x, int y, int *cx, int *cy, int *cw, int *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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props,
+eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
int x, int 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+ int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
{
evas_common_font_draw(surface, context, font, x, y, text, intl_props);
evas_common_draw_context_font_ext_set(context, NULL, NULL, NULL, NULL);
NULL, // ORD(image_map_surface_free);
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
- eng_font_pen_coords_get
+ eng_font_pen_coords_get,
+ eng_font_shape
/* FUTURE software generic calls go here */
};
}
static void
-eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h)
+eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h)
{
evas_common_font_query_size(font, text, intl_props, w, h);
}
}
static int
-eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
{
int h, v;
}
static int
-eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
{
int h, v;
}
static int
-eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
+eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
{
return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen_x, cy, cadv, ch);
}
+static Eina_Bool
+eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
+{
+ (void) font;
+ (void) text;
+ (void) intl_props;
+ (void) par_props;
+ (void) pos;
+ (void) len;
+#ifdef OT_SUPPORT
+ if (evas_common_font_ot_is_enabled())
+ {
+ return evas_common_font_ot_populate_text_props(font, text,
+ intl_props, len);
+ }
+ else
+#endif
+ {
+#ifdef BIDI_SUPPORT
+ return !evas_bidi_shape_string(text, par_props, pos, len);
+#endif
+ }
+ return EINA_TRUE;
+}
+
static int
-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)
+eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props, 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_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y)
+eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
#ifdef BUILD_PIPE_RENDER
if ((cpunum > 1)
eng_image_map_surface_free,
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
- eng_font_pen_coords_get
+ eng_font_pen_coords_get,
+ eng_font_shape
/* FUTURE software generic calls go here */
};
}
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
SDL_Engine_Image_Entry *eim = surface;
int mustlock_im = 0;
}
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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props)
+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_Text_Props *intl_props)
{
Render_Engine *re;
RGBA_Image *im;