+++ /dev/null
-#ifndef _EVAS_FONT_DEFAULT_WALK_X
-#define _EVAS_FONT_DEFAULT_WALK_X
-/* Macros for text walking */
-
-/**
- * @def EVAS_FONT_WALK_TEXT_INIT
- * @internal
- * This macro defines the variables that will later be used with the following
- * macros, and by font handling functions.
- * @see EVAS_FONT_WALK_TEXT_START
- * @see EVAS_FONT_WALK_TEXT_WORK
- * @see EVAS_FONT_WALK_TEXT_END
- */
-# define EVAS_FONT_WALK_TEXT_INIT() \
- int _pen_x = 0, _pen_y = 0; \
- size_t char_index; \
- (void) _pen_y; /* Sometimes it won't be used */
-
-/* Visual walk helper macros */
-#ifdef OT_SUPPORT
-#define _EVAS_FONT_WALK_TEXT_VISUAL_START() \
- Evas_Font_OT_Info *_ot_itr = (text_props->info) ? \
- text_props->info->ot + text_props->start : NULL; \
- for (char_index = 0 ; char_index < text_props->len ; char_index++, _glyph_itr++, _ot_itr++) \
- {
-#else
-#define _EVAS_FONT_WALK_TEXT_VISUAL_START() \
- for (char_index = 0 ; char_index < text_props->len ; char_index++, _glyph_itr++) \
- {
-#endif
-
-/**
- * @def EVAS_FONT_WALK_TEXT_VISUAL_START
- * @internal
- * This runs through the text in visual order while updating char_index,
- * which is the current index in the text.
- * Does not end with a ;
- * Take a look at EVAS_FONT_WALK_X_OFF and the like.
- * @see EVAS_FONT_WALK_TEXT_INIT
- * @see EVAS_FONT_WALK_TEXT_WORK
- * @see EVAS_FONT_WALK_TEXT_END
- * @see EVAS_FONT_WALK_TEXT_LOGICAL_START
- */
-#define EVAS_FONT_WALK_TEXT_VISUAL_START() \
- do \
- { \
- Evas_Font_Glyph_Info *_glyph_itr = (text_props->info) ? \
- text_props->info->glyph + text_props->start : NULL; \
- _EVAS_FONT_WALK_TEXT_VISUAL_START()
-
-/* Logical walk helper macros */
-#ifdef OT_SUPPORT
-#define _EVAS_FONT_WALK_TEXT_LOGICAL_START() \
- Evas_Font_OT_Info *_ot_itr = (text_props->info) ? \
- text_props->info->ot + text_props->start : NULL; \
- if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
- _ot_itr += text_props->len - 1; \
- for ( ; _i > 0 ; char_index += _char_index_d, _i--, _glyph_itr += _char_index_d, _ot_itr += _char_index_d) \
- {
-#else
-#define _EVAS_FONT_WALK_TEXT_LOGICAL_START() \
- for ( ; _i > 0 ; char_index += _char_index_d, _i--, _glyph_itr += _char_index_d) \
- {
-#endif
-
-/**
- * @def EVAS_FONT_WALK_TEXT_LOGICAL_START
- * @internal
- * This runs through the text in logical order while updating char_index,
- * which is the current index in the text.
- * Does not end with a ;
- * Take a look at EVAS_FONT_WALK_X_OFF and the like.
- * @see EVAS_FONT_WALK_TEXT_INIT
- * @see EVAS_FONT_WALK_TEXT_WORK
- * @see EVAS_FONT_WALK_TEXT_END
- * @see EVAS_FONT_WALK_TEXT_VISUAL_START
- */
-#ifdef BIDI_SUPPORT
-#define EVAS_FONT_WALK_TEXT_LOGICAL_START() \
- do \
- { \
- Evas_Font_Glyph_Info *_glyph_itr = (text_props->info) ? \
- text_props->info->glyph + text_props->start : \
- NULL; \
- int _char_index_d; \
- size_t _i; \
- _i = text_props->len; \
- if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
- { \
- char_index = text_props->len - 1; \
- _char_index_d = -1; \
- _glyph_itr += text_props->len - 1; \
- } \
- else \
- { \
- char_index = 0; \
- _char_index_d = 1; \
- } \
- _EVAS_FONT_WALK_TEXT_LOGICAL_START()
-
-#else
-#define EVAS_FONT_WALK_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
-#endif
-
-#define EVAS_FONT_WALK_ORIG_LEN (_len)
-
-/*FIXME: doc */
-#ifdef OT_SUPPORT
-# define EVAS_FONT_WALK_X_OFF \
- (EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(*_ot_itr)))
-# define EVAS_FONT_WALK_Y_OFF \
- (EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_Y_OFF_GET(*_ot_itr)))
-# define EVAS_FONT_WALK_POS \
- (EVAS_FONT_OT_POS_GET(*_ot_itr) - text_props->text_offset)
-# define EVAS_FONT_WALK_POS_NEXT \
- ((!EVAS_FONT_WALK_IS_LAST) ? \
- EVAS_FONT_OT_POS_GET(*(_ot_itr + 1)) - \
- text_props->text_offset : \
- EVAS_FONT_WALK_POS \
- )
-# define EVAS_FONT_WALK_POS_PREV \
- ((char_index > 0) ? \
- EVAS_FONT_OT_POS_GET(*(_ot_itr - 1)) - \
- text_props->text_offset : \
- EVAS_FONT_WALK_POS \
- )
-#else
-# define EVAS_FONT_WALK_X_OFF 0
-# define EVAS_FONT_WALK_Y_OFF 0
-# define EVAS_FONT_WALK_POS \
- ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
- (text_props->len - char_index - 1) : \
- (char_index))
-# define EVAS_FONT_WALK_POS_NEXT \
- ((!EVAS_FONT_WALK_IS_LAST) ? \
- ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
- text_props->len - char_index - 2 \
- : (char_index + 1)) : \
- EVAS_FONT_WALK_POS)
-# define EVAS_FONT_WALK_POS_PREV \
- ((char_index > 0) ? \
- ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
- text_props->len - char_index \
- : (char_index - 1)) : \
- EVAS_FONT_WALK_POS)
-#endif
-
-
-#define EVAS_FONT_WALK_IS_VISIBLE (_glyph_itr->index != 0)
-#define EVAS_FONT_WALK_X_BEAR (_glyph_itr->x_bear)
-#define EVAS_FONT_WALK_Y_BEAR (fg->glyph_out->top)
-#define _EVAS_FONT_WALK_X_ADV (_glyph_itr->advance)
-#define EVAS_FONT_WALK_WIDTH (_glyph_itr->width)
-
-#define EVAS_FONT_WALK_INDEX (_glyph_itr->index)
-#define EVAS_FONT_WALK_X_ADV \
- (EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_X_ADV))
-#define EVAS_FONT_WALK_PEN_X (EVAS_FONT_ROUND_26_6_TO_INT(_pen_x))
-#define EVAS_FONT_WALK_PEN_Y (EVAS_FONT_ROUND_26_6_TO_INT(_pen_y))
-#define EVAS_FONT_WALK_Y_ADV (0)
-#define EVAS_FONT_WALK_IS_LAST \
- (char_index + 1 == text_props->len)
-#define EVAS_FONT_WALK_IS_FIRST \
- (char_index == 0)
-#define EVAS_FONT_WALK_LEN (text_props->len)
-
-/**
- * @def EVAS_FONT_WALK_TEXT_WORK
- * @internal
- * This macro actually updates the values mentioned in EVAS_FONT_WALK_TEXT_VISUAL_START
- * according to the current positing in the walk.
- * @see EVAS_FONT_WALK_TEXT_VISUAL_START
- * @see EVAS_FONT_WALK_TEXT_INIT
- * @see EVAS_FONT_WALK_TEXT_END
- */
-#define EVAS_FONT_WALK_TEXT_WORK() do {} while(0)
-
-/**
- * @def EVAS_FONT_WALK_TEXT_END
- * @internal
- * Closes EVAS_FONT_WALK_TEXT_VISUAL_START, needs to end with a ;
- * @see EVAS_FONT_WALK_TEXT_VISUAL_START
- * @see EVAS_FONT_WALK_TEXT_INIT
- * @see EVAS_FONT_WALK_TEXT_WORK
- */
-#define EVAS_FONT_WALK_TEXT_END() \
- if (EVAS_FONT_WALK_IS_VISIBLE) \
- { \
- _pen_x += _EVAS_FONT_WALK_X_ADV; \
- } \
- } \
- } \
- while(0)
-
-
-#endif
+++ /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"
-
-#ifdef OT_SUPPORT
-/* FIXME: doc. returns #items */
-EAPI int
-evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index)
-{
- int i;
- int items;
- int left_bound, right_bound;
- size_t base_cluster;
- char_index += props->start;
- base_cluster = EVAS_FONT_OT_POS_GET(props->info->ot[char_index]);
- for (i = (int) char_index ;
- (i >= (int) props->start) &&
- (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
- i--)
- ;
- left_bound = i;
- for (i = (int) char_index + 1;
- (i < (int) (props->start + props->len)) &&
- (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
- i++)
- ;
- right_bound = i;
-
- if (right_bound == left_bound)
- {
- items = 1;
- }
- else if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
- {
- if (left_bound < 0)
- {
- items = props->text_offset + props->text_len - base_cluster;
- }
- else
- {
- items = props->info->ot[left_bound].source_cluster - base_cluster;
- }
- }
- else
- {
- if (right_bound >= (int) (props->text_offset + props->text_len))
- {
- items = props->text_offset + props->text_len - base_cluster;
- }
- else
- {
- items = props->info->ot[right_bound].source_cluster - base_cluster;
- }
- }
- return (items > 0) ? items : 1;
-}
-
-EAPI void
-evas_common_font_ot_load_face(void *_font)
-{
- RGBA_Font_Source *font = (RGBA_Font_Source *) _font;
- /* Unload the face if by any chance it's already loaded */
- evas_common_font_ot_unload_face(font);
- font->hb.face = hb_ft_face_create(font->ft.face, NULL);
-}
-
-EAPI void
-evas_common_font_ot_unload_face(void *_font)
-{
- RGBA_Font_Source *font = (RGBA_Font_Source *) _font;
- if (!font->hb.face) return;
- hb_face_destroy(font->hb.face);
- font->hb.face = NULL;
-}
-
-/* Harfbuzz font functions */
-static hb_font_funcs_t *_ft_font_funcs = NULL;
-
-static hb_codepoint_t
-_evas_common_font_ot_hb_get_glyph(hb_font_t *font, hb_face_t *face,
- const void *user_data, hb_codepoint_t unicode,
- hb_codepoint_t variation_selector)
-{
- RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
- return hb_font_funcs_get_glyph_func(_ft_font_funcs)(font, face,
- fi->src->ft.face, unicode, variation_selector);
-}
-
-static void
-_evas_common_font_ot_hb_get_glyph_advance(hb_font_t *font, hb_face_t *face,
- const void *user_data, hb_codepoint_t glyph,
- hb_position_t *x_advance, hb_position_t *y_advance)
-{
- /* Use our cache*/
- RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
- RGBA_Font_Glyph *fg;
- (void) font;
- (void) face;
- fg = evas_common_font_int_cache_glyph_get(fi, glyph);
- if (fg)
- {
- *x_advance = fg->glyph->advance.x >> 10;
- *y_advance = fg->glyph->advance.y >> 10;
- }
-}
-
-static void
-_evas_common_font_ot_hb_get_glyph_extents(hb_font_t *font, hb_face_t *face,
- const void *user_data, hb_codepoint_t glyph, hb_glyph_extents_t *extents)
-{
- RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
- hb_font_funcs_get_glyph_extents_func(_ft_font_funcs)(font, face,
- fi->src->ft.face, glyph, extents);
-}
-
-static hb_bool_t
-_evas_common_font_ot_hb_get_contour_point(hb_font_t *font, hb_face_t *face,
- const void *user_data, unsigned int point_index, hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
-{
- RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
- return hb_font_funcs_get_contour_point_func(_ft_font_funcs)(font, face,
- fi->src->ft.face, point_index, glyph, x, y);
-}
-
-static hb_position_t
-_evas_common_font_ot_hb_get_kerning(hb_font_t *font, hb_face_t *face,
- const void *user_data, hb_codepoint_t first_glyph,
- hb_codepoint_t second_glyph)
-{
- RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
- int kern;
- (void) font;
- (void) face;
- if (evas_common_font_query_kerning(fi, first_glyph, second_glyph, &kern))
- return kern;
- else
- return 0;
-}
-
-/* End of harfbuzz font funcs */
-
-static hb_font_funcs_t *
-_evas_common_font_ot_font_funcs_get(void)
-{
- static hb_font_funcs_t *font_funcs = NULL;
- if (!font_funcs)
- {
- _ft_font_funcs = hb_ft_get_font_funcs();
- font_funcs = hb_font_funcs_create();
- hb_font_funcs_set_glyph_func(font_funcs,
- _evas_common_font_ot_hb_get_glyph);
- hb_font_funcs_set_glyph_advance_func(font_funcs,
- _evas_common_font_ot_hb_get_glyph_advance);
- hb_font_funcs_set_glyph_extents_func(font_funcs,
- _evas_common_font_ot_hb_get_glyph_extents);
- hb_font_funcs_set_contour_point_func(font_funcs,
- _evas_common_font_ot_hb_get_contour_point);
- hb_font_funcs_set_kerning_func(font_funcs,
- _evas_common_font_ot_hb_get_kerning);
- }
-
- return font_funcs;
-}
-
-static void
-_evas_common_font_ot_shape(hb_buffer_t *buffer, RGBA_Font_Int *fi)
-{
- hb_font_t *hb_font;
-
- hb_font = hb_ft_font_create(fi->src->ft.face, NULL);
- hb_font_set_funcs(hb_font, _evas_common_font_ot_font_funcs_get(), NULL, fi);
-
- hb_shape(hb_font, fi->src->hb.face, buffer, NULL, 0);
- hb_font_destroy(hb_font);
-}
-
-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;
-
- fi = fn->fonts->data;
- /* Load the font needed for this script */
- {
- /* Skip common chars */
- const Eina_Unicode *tmp;
- for (tmp = text ;
- *tmp &&
- evas_common_language_char_script_get(*tmp) == EVAS_SCRIPT_COMMON ;
- tmp++)
- ;
- if (!*tmp && (tmp > text)) tmp--;
- evas_common_font_glyph_search(fn, &fi, *tmp);
- }
- evas_common_font_int_reload(fi);
- if (fi->src->current_size != fi->size)
- {
- FTLOCK();
- FT_Activate_Size(fi->ft.size);
- FTUNLOCK();
- fi->src->current_size = fi->size;
- }
-
- 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);
-
- props->len = hb_buffer_get_length(buffer);
- props->info->ot = calloc(props->len,
- sizeof(Evas_Font_OT_Info));
- props->info->glyph = calloc(props->len,
- sizeof(Evas_Font_Glyph_Info));
- positions = hb_buffer_get_glyph_positions(buffer);
- infos = hb_buffer_get_glyph_infos(buffer);
- for (i = 0 ; i < props->len ; i++)
- {
- props->info->ot[i].source_cluster = infos[i].cluster;
- props->info->ot[i].x_offset = positions[i].x_offset;
- props->info->ot[i].y_offset = positions[i].y_offset;
- props->info->glyph[i].index = infos[i].codepoint;
- props->info->glyph[i].advance = positions[i].x_advance;
- }
-
- hb_buffer_destroy(buffer);
- evas_common_font_int_use_trim();
-
- return EINA_FALSE;
-}
-
-#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_Info Evas_Font_OT_Info;
-# else
-typedef void *Evas_Font_OT_Info;
-# endif
-
-# include "Evas.h"
-
-# ifdef OT_SUPPORT
-struct _Evas_Font_OT_Info
-{
- size_t source_cluster;
- Evas_Coord x_offset;
- Evas_Coord y_offset;
-};
-# 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_POS_GET(a) ((a).source_cluster)
-# endif
-
-EAPI void
-evas_common_font_ot_load_face(void *_font);
-
-EAPI void
-evas_common_font_ot_unload_face(void *_font);
-
-# include "evas_text_utils.h"
-EAPI int
-evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index);
-
-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
-#include "evas_common.h"
-#include "evas_font_private.h"
-#include "evas_text_utils.h"
-#include "language/evas_bidi_utils.h"
-#include "language/evas_language_utils.h"
-#include "evas_font_ot.h"
-
-/* Used for showing "malformed" or missing chars */
-#define REPLACEMENT_CHAR 0xFFFD
-
-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));
- evas_common_text_props_content_ref(dst);
-}
-
-void
-evas_common_text_props_content_ref(Evas_Text_Props *props)
-{
- /* No content in this case */
- if (!props->info)
- return;
-
- props->info->refcount++;
-}
-
-void
-evas_common_text_props_content_unref(Evas_Text_Props *props)
-{
- /* No content in this case */
- if (!props->info)
- return;
-
- if (--(props->info->refcount) == 0)
- {
- if (props->info->glyph)
- free(props->info->glyph);
-#ifdef OT_SUPPORT
- if (props->info->ot)
- free(props->info->ot);
-#endif
- free(props->info);
- props->info = NULL;
- }
-}
-
-/* Won't work in the middle of ligatures, assumes cutoff < len */
-EAPI void
-evas_common_text_props_split(Evas_Text_Props *base,
- Evas_Text_Props *ext, int _cutoff)
-{
- size_t cutoff;
-
- /* Translate text cutoff pos to string object cutoff point */
-#ifdef OT_SUPPORT
- cutoff = 0;
-
- {
- Evas_Font_OT_Info *itr;
- size_t i;
- itr = base->info->ot + base->start;
- _cutoff += base->text_offset;
- /* FIXME: can I binary search? I don't think this is always sorted */
- for (i = 0 ; i < base->len ; i++, itr++)
- {
- if (itr->source_cluster == (size_t) _cutoff)
- {
- if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
- {
- /* Walk to the last one of the same cluster */
- for ( ; i < base->len ; i++, itr++)
- {
- if (itr->source_cluster != (size_t) _cutoff)
- break;
- }
- cutoff = base->len - i;
- }
- else
- {
- cutoff = i;
- }
- break;
- }
- }
- }
-
- /* If we didn't find a reasonable cut location, return. */
- if (cutoff == 0)
- {
- ERR("Couldn't find the cutoff position. Is it inside a cluster?");
- return;
- }
-#else
- cutoff = (size_t) _cutoff;
-#endif
-
- evas_common_text_props_content_copy_and_ref(ext, base);
- if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
- {
- ext->start = base->start;
- ext->len = base->len - cutoff;
- base->start = (base->start + base->len) - cutoff;
- base->len = cutoff;
-
-#ifdef OT_SUPPORT
- ext->text_offset =
- ext->info->ot[ext->start + ext->len - 1].source_cluster;
-#else
- ext->text_offset = base->text_offset + base->len;
-#endif
- }
- else
- {
- ext->start = base->start + cutoff;
- ext->len = base->len - cutoff;
- base->len = cutoff;
-
-#ifdef OT_SUPPORT
- ext->text_offset = ext->info->ot[ext->start].source_cluster;
-#else
- ext->text_offset = base->text_offset + base->len;
-#endif
- }
- ext->text_len = base->text_len - (ext->text_offset - base->text_offset);
- base->text_len = (ext->text_offset - base->text_offset);
-}
-
-/* Won't work in the middle of ligatures */
-EAPI void
-evas_common_text_props_merge(Evas_Text_Props *item1,
- const Evas_Text_Props *item2)
-{
- if (item1->info != item2->info)
- {
- ERR("tried merge back items that weren't together in the first place.");
- return;
- }
- if (item1->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
- {
- item1->start = item2->start;
- }
-
- item1->len += item2->len;
- item1->text_len += item2->text_len;
-}
-
-EAPI Eina_Bool
-evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
- Evas_Text_Props *text_props, int len)
-{
- RGBA_Font *fn = (RGBA_Font *) _fn;
- RGBA_Font_Int *fi;
- size_t char_index;
-
- if (text_props->info)
- {
- evas_common_text_props_content_unref(text_props);
- }
- if (len == 0)
- {
- text_props->info = NULL;
- text_props->start = text_props->len = text_props->text_offset = 0;
- }
- text_props->info = calloc(1, sizeof(Evas_Text_Props_Info));
-
- fi = fn->fonts->data;
- /* evas_common_font_size_use(fn); */
- evas_common_font_int_reload(fi);
- if (fi->src->current_size != fi->size)
- {
- FTLOCK();
- FT_Activate_Size(fi->ft.size);
- FTUNLOCK();
- fi->src->current_size = fi->size;
- }
-
-#ifdef OT_SUPPORT
- const Eina_Unicode *base_char;
- evas_common_font_ot_populate_text_props(fn, text, text_props, len);
-
- /* Load the glyph according to the first letter of the script, preety
- * bad, but will have to do */
- {
- /* Skip common chars */
- for (base_char = text ;
- *base_char &&
- evas_common_language_char_script_get(*base_char) ==
- EVAS_SCRIPT_COMMON ;
- base_char++)
- ;
- if (!*base_char && (base_char > text)) base_char--;
- evas_common_font_glyph_search(fn, &fi, *base_char);
- }
-
- for (char_index = 0 ; char_index < text_props->len ; char_index++)
- {
- FT_UInt index;
- RGBA_Font_Glyph *fg;
- Eina_Bool is_replacement = EINA_FALSE;
- /* If we got a malformed index, show the replacement char instead */
- if (text_props->info->glyph[char_index].index == 0)
- {
- text_props->info->glyph[char_index].index =
- evas_common_font_glyph_search(fn, &fi, REPLACEMENT_CHAR);
- is_replacement = EINA_TRUE;
- }
- index = text_props->info->glyph[char_index].index;
- LKL(fi->ft_mutex);
- fg = evas_common_font_int_cache_glyph_get(fi, index);
- if (!fg)
- {
- LKU(fi->ft_mutex);
- continue;
- }
- LKU(fi->ft_mutex);
- if (is_replacement)
- {
- /* Update the advance accordingly */
- text_props->info->glyph[char_index].advance =
- fg->glyph->advance.x >> 10;
- /* FIXME: reload fi, a bit slow, but I have no choice. */
- evas_common_font_glyph_search(fn, &fi, *base_char);
- }
- text_props->info->glyph[char_index].x_bear =
- fg->glyph_out->left;
- text_props->info->glyph[char_index].width =
- fg->glyph_out->bitmap.width;
- /* text_props->info->glyph[char_index].advance =
- * text_props->info->glyph[char_index].index =
- * already done by the ot function */
- if (EVAS_FONT_CHARACTER_IS_INVISIBLE(
- text[text_props->info->ot[char_index].source_cluster]))
- text_props->info->glyph[char_index].index = 0;
-
- }
-#else
- /* We are walking the string in visual ordering */
- Eina_Bool use_kerning;
- FT_UInt prev_index;
- FT_Face pface = NULL;
- int adv_d, i;
- FTLOCK();
- use_kerning = FT_HAS_KERNING(fi->src->ft.face);
- FTUNLOCK();
- prev_index = 0;
-
- i = len;
- text_props->info->glyph = calloc(len,
- sizeof(Evas_Font_Glyph_Info));
-
- if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
- {
- text += len - 1;
- adv_d = -1;
- }
- else
- {
- adv_d = 1;
- }
- char_index = 0;
- for ( ; i > 0 ; char_index++, text += adv_d, i--)
- {
- FT_UInt index;
- RGBA_Font_Glyph *fg;
- int _gl, kern;
- _gl = *text;
- if (_gl == 0) break;
-
- index = evas_common_font_glyph_search(fn, &fi, _gl);
- if (index == 0)
- {
- index = evas_common_font_glyph_search(fn, &fi, REPLACEMENT_CHAR);
- }
- LKL(fi->ft_mutex);
- fg = evas_common_font_int_cache_glyph_get(fi, index);
- if (!fg)
- {
- LKU(fi->ft_mutex);
- continue;
- }
- kern = 0;
-
- if ((use_kerning) && (prev_index) && (index) &&
- (pface == fi->src->ft.face))
- {
-# ifdef BIDI_SUPPORT
- /* if it's rtl, the kerning matching should be reversed, */
- /* i.e prev index is now the index and the other way */
- /* around. There is a slight exception when there are */
- /* compositing chars involved.*/
- if (text_props &&
- (text_props->bidi.dir != EVAS_BIDI_DIRECTION_RTL))
- {
- if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
- {
- text_props->info->glyph[char_index - 1].advance +=
- kern;
- }
- }
- else
-# endif
- {
- if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
- {
- text_props->info->glyph[char_index - 1].advance +=
- kern;
- }
- }
- }
-
- pface = fi->src->ft.face;
- LKU(fi->ft_mutex);
-
- if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl))
- text_props->info->glyph[char_index].index = 0;
-
- text_props->info->glyph[char_index].index = index;
- text_props->info->glyph[char_index].x_bear =
- fg->glyph_out->left;
- text_props->info->glyph[char_index].advance =
- fg->glyph->advance.x >> 10;
- text_props->info->glyph[char_index].width =
- fg->glyph_out->bitmap.width;
-
- prev_index = index;
- }
- text_props->len = len;
-#endif
- text_props->text_len = len;
- text_props->info->refcount = 1;
- return EINA_TRUE;
-}
-
+++ /dev/null
-#ifndef _EVAS_TEXT_UTILS_H
-# define _EVAS_TEXT_UTILS_H
-
-typedef struct _Evas_Text_Props Evas_Text_Props;
-typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info;
-typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info;
-
-# include "evas_font_ot.h"
-# include "language/evas_bidi_utils.h"
-# include "language/evas_language_utils.h"
-
-struct _Evas_Text_Props
-{
- /* Start and len represent the start offset and the length in the
- * glyphs_info and ot_data fields, they are both internal */
- size_t start;
- size_t len;
- size_t text_offset; /* The text offset from the start of the info */
- size_t text_len; /* The length of the original text */
- Evas_BiDi_Props bidi;
- Evas_Script_Type script;
- Evas_Text_Props_Info *info;
-};
-
-struct _Evas_Text_Props_Info
-{
- unsigned int refcount;
- Evas_Font_Glyph_Info *glyph;
- Evas_Font_OT_Info *ot;
-};
-
-/* Sorted in visual order when created */
-struct _Evas_Font_Glyph_Info
-{
- unsigned int index; /* Should conform to FT */
- Evas_Coord x_bear;
-#if 0
- /* This one is rarely used, only in draw, in which we already get the glyph
- * so it doesn't really save time. Leaving it here just so no one will
- * add it thinking it was accidentally skipped */
- Evas_Coord y_bear;
-#endif
- Evas_Coord width;
- Evas_Coord advance;
-};
-
-
-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);
-
-EAPI Eina_Bool
-evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
- Evas_Text_Props *text_props, int len);
-
-void
-evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
- const Evas_Text_Props *src);
-
-void
-evas_common_text_props_content_ref(Evas_Text_Props *props);
-
-void
-evas_common_text_props_content_unref(Evas_Text_Props *props);
-
-
-EAPI void
-evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext,
- int cutoff);
-EAPI void
-evas_common_text_props_merge(Evas_Text_Props *item1, const Evas_Text_Props *item2);
-#endif
+++ /dev/null
-#include <string.h>
-#include <stdlib.h>
-
-#include "evas_common.h"
-#include "evas_bidi_utils.h"
-
-#include "evas_font_private.h"
-
-#ifdef BIDI_SUPPORT
-#include <fribidi/fribidi.h>
-/**
- * @internal
- * @addtogroup Evas_Utils
- *
- * @{
- */
-/**
- * @internal
- * @addtogroup Evas_BiDi
- *
- * @{
- */
-
-/**
- * @internal
- * @def _SAFE_FREE(x)
- * checks if x is not NULL, if it's not, it's freed and set to NULL.
- */
-#define _SAFE_FREE(x) \
- do { \
- if (x) \
- { \
- free(x); \
- x = NULL; \
- } \
- } while(0)
-
-/* Convert bidichar to eina_unicode assume both are valid pointers */
-static Eina_Unicode *
-_evas_bidi_fribidichar_to_unicode(Eina_Unicode *dest, const FriBidiChar *src)
-{
- Eina_Unicode *ret = dest;
-
- while (*src)
- *dest++ = *src++;
- *dest = 0;
- return ret;
-}
-
-/* Convert eina_unicode to bidi_char assume both are valid pointers */
-static FriBidiChar *
-_evas_bidi_unicode_to_fribidichar(FriBidiChar *dest, const Eina_Unicode *src)
-{
- FriBidiChar *ret = dest;
-
- while (*src)
- *dest++ = *src++;
- *dest = 0;
- return ret;
-}
-
-/**
- * @internal
- * Checks if the string has RTL characters.
- *
- * @param str The string to be checked
- * @return #EINA_TRUE if true, #EINA_FALSE otherwise.
- */
-Eina_Bool
-evas_bidi_is_rtl_str(const Eina_Unicode *str)
-{
- EvasBiDiCharType type;
-
- if (!str)
- return EINA_FALSE;
-
- for ( ; *str ; str++)
- {
- type = fribidi_get_bidi_type((FriBidiChar) *str);
- if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type))
- {
- return EINA_TRUE;
- }
- }
- return EINA_FALSE;
-}
-
-/**
- * @internal
- * Shapes the string ustr according to the bidi properties.
- *
- * @param str The string to shape
- * @param bidi_props the bidi props to shaped according.
- * @param start the start of the string to shape (offset in bidi_props)
- * @param len the length of th string.
- * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
- */
-EAPI Eina_Bool
-evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, size_t len)
-{
- FriBidiChar *ustr, *base_ustr = NULL;
-
- if (!bidi_props)
- return EINA_FALSE;
-
- /* The size of fribidichar is different than eina_unicode, convert */
- /*FIXME: Make this comparison at compile time and compile out
- * unwanted code. - In all of this source file. (including the actual
- * function declerations. */
- if (sizeof(Eina_Unicode) != sizeof(FriBidiChar))
- {
- base_ustr = ustr = calloc(len + 1, sizeof(FriBidiChar));
- ustr = _evas_bidi_unicode_to_fribidichar(ustr, eina_ustr);
- }
- else
- {
- ustr = (FriBidiChar *) eina_ustr;
- }
-
-
- EvasBiDiJoiningType *join_types = NULL;
- join_types = (EvasBiDiJoiningType *) malloc(sizeof(EvasBiDiJoiningType) * len);
- if (!join_types)
- {
- return EINA_FALSE;
- }
- fribidi_get_joining_types(ustr, len, join_types);
-
- fribidi_join_arabic(bidi_props->char_types + start, len,
- bidi_props->embedding_levels + start, join_types);
-
-
- /* Actually modify the string */
- fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC,
- bidi_props->embedding_levels + start, len, join_types, ustr);
-
- if (join_types) free(join_types);
-
- /* Convert back */
- if (sizeof(Eina_Unicode) != sizeof(FriBidiChar))
- {
- eina_ustr = _evas_bidi_fribidichar_to_unicode(eina_ustr, ustr);
- if (base_ustr) free(base_ustr);
- }
- return EINA_TRUE;
-}
-
-/**
- * @internal
- * Allocates bidi properties according to ustr. First checks to see if the
- * passed has rtl chars, if not, it returns NULL.
- *
- * @param ustr The string to update according to.
- * @return returns allocated paragraph props on success, NULL otherwise.
- */
-
-Evas_BiDi_Paragraph_Props *
-evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr)
-{
- Evas_BiDi_Paragraph_Props *bidi_props = NULL;
- EvasBiDiCharType *char_types = NULL;
- EvasBiDiLevel *embedding_levels = NULL;
- const FriBidiChar *ustr;
- FriBidiChar *base_ustr = NULL;
- size_t len;
-
- if (!eina_ustr)
- return NULL;
-
-
- if (!evas_bidi_is_rtl_str(eina_ustr)) /* No need to handle bidi */
- {
- len = -1;
- goto cleanup;
- }
-
- len = eina_unicode_strlen(eina_ustr);
- /* The size of fribidichar s different than eina_unicode, convert */
- if (sizeof(Eina_Unicode) != sizeof(FriBidiChar))
- {
- base_ustr = calloc(len + 1, sizeof(FriBidiChar));
- base_ustr = _evas_bidi_unicode_to_fribidichar(base_ustr, eina_ustr);
- ustr = base_ustr;
- }
- else
- {
- ustr = (const FriBidiChar *) eina_ustr;
- }
-
- bidi_props = evas_bidi_paragraph_props_new();
-
- /* Prep work for reordering */
- char_types = (EvasBiDiCharType *) malloc(sizeof(EvasBiDiCharType) * len);
- if (!char_types)
- {
- len = -2;
- goto cleanup;
- }
- fribidi_get_bidi_types(ustr, len, char_types);
-
- embedding_levels = (EvasBiDiLevel *)malloc(sizeof(EvasBiDiLevel) * len);
- if (!embedding_levels)
- {
- len = -2;
- goto cleanup;
- }
- if (!fribidi_get_par_embedding_levels(char_types, len, &bidi_props->direction, embedding_levels))
- {
- len = -2;
- goto cleanup;
- }
-
-
- /* clean up */
- if (bidi_props->embedding_levels)
- {
- free(bidi_props->embedding_levels);
- }
- bidi_props->embedding_levels = embedding_levels;
-
- /* clean up */
-
- if (bidi_props->char_types)
- {
- free(bidi_props->char_types);
- }
- bidi_props->char_types = char_types;
-
- if (base_ustr) free(base_ustr);
-
-
- return bidi_props;
-
-/* Cleanup */
-cleanup:
- if (char_types) free(char_types);
- if (embedding_levels) free(embedding_levels);
- if (base_ustr) free(base_ustr);
- if (bidi_props) evas_bidi_paragraph_props_unref(bidi_props); /* Clean up the bidi props */
- return NULL;
-}
-
-/**
- * @internal
- * Copies dst to src and refs (doesn't copy) the paragraph props.
- *
- * @param src the props to copy
- * @param dst the props to copy to.
- */
-void
-evas_bidi_props_copy_and_ref(const Evas_BiDi_Props *src, Evas_BiDi_Props *dst)
-{
- dst->dir = src->dir;
-}
-
-/**
- * @internal
- * Reorders ustr according to the bidi props.
- *
- * @param ustr the string to reorder. - Null is ok, will just populate the map.
- * @param start the start of the line
- * @param len the length of the line
- * @param props the paragraph props to reorder according to
- * @param _v_to_l The visual to logical map to populate - if NULL it won't populate it.
- * @return #EINA_FALSE on success, #EINA_TRUE on error.
- */
-Eina_Bool
-evas_bidi_props_reorder_line(Eina_Unicode *eina_ustr, size_t start, size_t len, const Evas_BiDi_Paragraph_Props *props, EvasBiDiStrIndex **_v_to_l)
-{
- EvasBiDiStrIndex *v_to_l = NULL;
- FriBidiChar *ustr = NULL, *base_ustr = NULL;
-
- if (!props)
- return EINA_FALSE;
-
- if (eina_ustr)
- {
- /* The size of fribidichar is different than eina_unicode, convert */
- if (sizeof(Eina_Unicode) != sizeof(FriBidiChar))
- {
- base_ustr = ustr = calloc(len + 1, sizeof(FriBidiChar));
- ustr = _evas_bidi_unicode_to_fribidichar(ustr, eina_ustr);
- }
- else
- {
- ustr = (FriBidiChar *) eina_ustr;
- }
- }
-
-
- if (_v_to_l) {
- size_t i;
- v_to_l = *_v_to_l = calloc(len, sizeof(EvasBiDiStrIndex));
- if (!v_to_l)
- {
- goto error;
- }
- /* init the array for fribidi */
- for (i = 0 ; i < len ; i++)
- {
- v_to_l[i] = i;
- }
- }
-
- /* Shaping must be done *BEFORE* breaking to lines so there's no choice but
- doing it in textblock. */
- {
- /* FIXME: Hack around fribidi altering embedding_levels */
- EvasBiDiLevel *emb_lvl;
- emb_lvl = malloc(len * sizeof(EvasBiDiLevel));
- memcpy(emb_lvl, props->embedding_levels, len * sizeof(EvasBiDiLevel));
- if (!fribidi_reorder_line (FRIBIDI_FLAGS_DEFAULT,
- props->char_types + start,
- len, 0, props->direction,
- emb_lvl,
- ustr, v_to_l))
- {
- free(emb_lvl);
- goto error;
- }
- free(emb_lvl);
- }
-
-
- /* The size of fribidichar is different than eina_unicode, convert */
- if (sizeof(Eina_Unicode) != sizeof(FriBidiChar))
- {
- _evas_bidi_fribidichar_to_unicode(eina_ustr, base_ustr);
- free(base_ustr);
- }
- return EINA_FALSE;
-/* ERROR HANDLING */
-error:
- if (base_ustr) free(base_ustr);
- _SAFE_FREE(v_to_l);
- return EINA_TRUE;
-}
-
-/**
- * @internal
- * Returns the end of the current run of text
- *
- * @param bidi_props the paragraph properties
- * @param start where to start looking from
- * @param len the length of the string
- * @return the position of the end of the run (offset from
- * bidi_props->props->start), 0 when there is no end (i.e all the text)
- */
-int
-evas_bidi_end_of_run_get(const Evas_BiDi_Paragraph_Props *bidi_props,
- size_t start, int len)
-{
- EvasBiDiLevel *i;
- EvasBiDiLevel base;
-
- if (!bidi_props || (len <= 0))
- return 0;
-
- i = bidi_props->embedding_levels + start;
- base = *i;
- for ( ; (len > 0) && (base == *i) ; len--, i++)
- ;
-
- if (len == 0)
- {
- return 0;
- }
- return i - (bidi_props->embedding_levels + start);
-}
-
-/**
- * @internal
- * Returns the visual string index from the logical string index.
- *
- * @param v_to_l the visual to logical map
- * @param len the length of the map.
- * @param position the position to convert.
- * @return on success the visual position, on failure the same position.
- */
-EvasBiDiStrIndex
-evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDiStrIndex position)
-{
- int i;
- EvasBiDiStrIndex *ind;
- if (position >= len || !v_to_l)
- return position;
-
- for (i = 0, ind = v_to_l ; i < len ; i++, ind++)
- {
- if (*ind == position)
- {
- return i;
- }
- }
- return position;
-}
-
-/**
- * @internal
- * Returns the reversed pos of the index.
- *
- * @param dir the direction of the string
- * @param len the length of the map.
- * @param position the position to convert.
- * @return on success the visual position, on failure the same position.
- */
-EvasBiDiStrIndex
-evas_bidi_position_reverse(const Evas_BiDi_Props *props, int len, EvasBiDiStrIndex position)
-{
- if (!props || position >= len)
- return position;
-
- return (props->dir == EVAS_BIDI_DIRECTION_RTL) ? (len - 1) - position : position;
-}
-
-/**
- * @internal
- * Checks if the char is rtl oriented. I.e even a neutral char can become rtl
- * if surrounded by rtl chars.
- *
- * @param bidi_props The bidi paragraph properties
- * @param start the base position
- * @param index the offset from the base position.
- * @return #EINA_TRUE if true, #EINA_FALSE otherwise.
- */
-Eina_Bool
-evas_bidi_is_rtl_char(const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, EvasBiDiStrIndex index)
-{
- if(!bidi_props || index < 0)
- return EINA_FALSE;
- return (FRIBIDI_IS_RTL(
- bidi_props->embedding_levels[index + start]))
- ? EINA_TRUE : EINA_FALSE;
-}
-
-Evas_BiDi_Paragraph_Props *
-evas_bidi_paragraph_props_new(void)
-{
- Evas_BiDi_Paragraph_Props *ret;
- ret = calloc(1, sizeof(Evas_BiDi_Paragraph_Props));
- ret->direction = EVAS_BIDI_PARAGRAPH_NATURAL;
- ret->refcount = 1;
-
- return ret;
-}
-
-/**
- * @internal
- * Refs the bidi props.
- *
- * @param bidi_props the props to ref.
- */
-Evas_BiDi_Paragraph_Props *
-evas_bidi_paragraph_props_ref(Evas_BiDi_Paragraph_Props *bidi_props)
-{
- if (!bidi_props) return NULL;
- BIDILOCK();
-
- bidi_props->refcount++;
- BIDIUNLOCK();
- return bidi_props;
-}
-
-/**
- * @internal
- * Unrefs and potentially frees the props.
- *
- * @param bidi_props the properties to unref
- */
-void
-evas_bidi_paragraph_props_unref(Evas_BiDi_Paragraph_Props *bidi_props)
-{
- if (!bidi_props) return;
- BIDILOCK();
-
- if (--bidi_props->refcount == 0)
- {
- evas_bidi_paragraph_props_clean(bidi_props);
- free(bidi_props);
- }
- BIDIUNLOCK();
-}
-
-
-/**
- * @internal
- * Cleans the paragraph properties.
- *
- * @param bidi_props the properties to clean.
- */
-void
-evas_bidi_paragraph_props_clean(Evas_BiDi_Paragraph_Props *bidi_props)
-{
- _SAFE_FREE(bidi_props->embedding_levels);
- _SAFE_FREE(bidi_props->char_types);
-}
-
-/**
- * @internal
- * Cleans the bidi properties.
- *
- * @param bidi_props the properties to clean.
- */
-void
-evas_bidi_props_clean(Evas_BiDi_Props *bidi_props)
-{
- if (!bidi_props) return;
- bidi_props->dir = EVAS_BIDI_DIRECTION_NATURAL;
-}
-/**
- * @}
- */
-/**
- * @}
- */
-#endif
-
+++ /dev/null
-#ifndef _EVAS_BIDI_UTILS
-#define _EVAS_BIDI_UTILS
-
-/**
- * @internal
- * @addtogroup Evas_Utils
- *
- * @{
- */
-/**
- * @internal
- * @defgroup Evas_BiDi Evas BiDi utility functions
- *
- * This set of functions and types helps evas handle BiDi strings correctly.
- * @todo Document types, structures and macros.
- *
- * @{
- */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef HAVE_FRIBIDI
-# define USE_FRIBIDI
-# define BIDI_SUPPORT
-#endif
-
-#include <Eina.h>
-
-#ifdef USE_FRIBIDI
-# include <fribidi/fribidi.h>
-#endif
-
-/* abstract fribidi - we statically define sizes here because otherwise we would
- * have to ifdef everywhere (because function decorations may change with/without
- * bidi support)
- * These types should only be passed as pointers! i.e do not directely use any of
- * these types in function declarations. Defining as void should help ensuring that.
- */
-
-/* Evas_BiDi_Direction is defined in evas.h */
-
-#ifdef USE_FRIBIDI
-# define _EVAS_BIDI_TYPEDEF(type) \
- typedef FriBidi ## type EvasBiDi ## type
-#else
-# define _EVAS_BIDI_TYPEDEF(type) \
- typedef void EvasBiDi ## type
-#endif
-
-#if 0 /* We are using Eina_Unicode instead */
-_EVAS_BIDI_TYPEDEF(Char);
-#endif
-_EVAS_BIDI_TYPEDEF(CharType);
-_EVAS_BIDI_TYPEDEF(ParType);
-_EVAS_BIDI_TYPEDEF(StrIndex);
-_EVAS_BIDI_TYPEDEF(Level);
-_EVAS_BIDI_TYPEDEF(JoiningType);
-
-typedef struct _Evas_BiDi_Paragraph_Props Evas_BiDi_Paragraph_Props;
-typedef struct _Evas_BiDi_Props Evas_BiDi_Props;
-
-/* This structure defines a set of properties of a BiDi string. In case of a
- * non-bidi string, all values should be NULL.
- * To check if a structure describes a bidi string or not, use the macro
- * EVAS_BIDI_IS_BIDI_PROP. RTL-only strings are also treated as bidi ATM.
- */
-struct _Evas_BiDi_Paragraph_Props {
- EvasBiDiCharType *char_types; /* BiDi char types */
- EvasBiDiLevel *embedding_levels; /* BiDi embedding levels */
- int refcount; /* The number of references to this object */
-#ifdef USE_FRIBIDI
- EvasBiDiParType direction;
-#endif
-};
-
-#include "Evas.h"
-struct _Evas_BiDi_Props
-{
- Evas_BiDi_Direction dir;
-};
-
-
-
-#ifdef USE_FRIBIDI
-
-
-#define EVAS_BIDI_PARAGRAPH_NATURAL FRIBIDI_PAR_ON
-#define EVAS_BIDI_PARAGRAPH_LTR FRIBIDI_PAR_LTR
-#define EVAS_BIDI_PARAGRAPH_RTL FRIBIDI_PAR_RTL
-#define EVAS_BIDI_PARAGRAPH_WLTR FRIBIDI_PAR_WLTR
-#define EVAS_BIDI_PARAGRAPH_WRTL FRIBIDI_PAR_WRTL
-
-#define EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(x) \
- (((x) && \
- ((x->direction == EVAS_BIDI_PARAGRAPH_RTL) || \
- (x->direction == EVAS_BIDI_PARAGRAPH_WRTL))) ? \
- EINA_TRUE : EINA_FALSE)
-
-
-# define evas_bidi_position_visual_to_logical(list, position) \
- (list) ? list[position] : position;
-
-EvasBiDiStrIndex
-evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDiStrIndex position);
-
-EvasBiDiStrIndex
-evas_bidi_position_reverse(const Evas_BiDi_Props *props, int len, EvasBiDiStrIndex position);
-
-Eina_Bool
-evas_bidi_is_rtl_str(const Eina_Unicode *str);
-
-Eina_Bool
-evas_bidi_is_rtl_char(const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, EvasBiDiStrIndex index);
-
-int
-evas_bidi_end_of_run_get(const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len);
-
-Eina_Bool
-evas_bidi_props_reorder_line(Eina_Unicode *eina_ustr, size_t start, size_t len, const Evas_BiDi_Paragraph_Props *props, EvasBiDiStrIndex **_v_to_l);
-
-Evas_BiDi_Paragraph_Props *
-evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr) EINA_ARG_NONNULL(1) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
-
-void
-evas_bidi_props_copy_and_ref(const Evas_BiDi_Props *src, Evas_BiDi_Props *dst);
-
-EAPI Eina_Bool
-evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, size_t len);
-
-void
-evas_bidi_props_clean(Evas_BiDi_Props *intl_props) EINA_ARG_NONNULL(1);
-
-void
-evas_bidi_paragraph_props_clean(Evas_BiDi_Paragraph_Props *bidi_props) EINA_ARG_NONNULL(1);
-
-Evas_BiDi_Paragraph_Props *
-evas_bidi_paragraph_props_ref(Evas_BiDi_Paragraph_Props *bidi_props) EINA_ARG_NONNULL(1);
-
-void
-evas_bidi_paragraph_props_unref(Evas_BiDi_Paragraph_Props *bidi_props) EINA_ARG_NONNULL(1);
-
-Evas_BiDi_Paragraph_Props *
-evas_bidi_paragraph_props_new(void) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
-
-#endif
-/**
- * @}
- */
-/**
- * @}
- */
-
-#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_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;
-}
-
-Evas_Script_Type
-evas_common_language_char_script_get(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 */
-#ifdef OT_SUPPORT
- Evas_Script_Type first = EVAS_SCRIPT_UNKNOWN;
- int i;
- for (i = 0 ; i < len ; i++, str++)
- {
- Evas_Script_Type tmp;
- tmp = evas_common_language_char_script_get(*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;
-#elif defined(BIDI_SUPPORT)
- (void) str;
- return evas_bidi_end_of_run_get(bidi_props, start, len);
-#else
- (void) bidi_props;
- (void) start;
- (void) str;
- (void) len;
- return 0;
-#endif
-}
-
-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 = evas_common_language_char_script_get(*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);
-
-Evas_Script_Type
-evas_common_language_char_script_get(Eina_Unicode unicode);
-
-const char *
-evas_common_language_from_locale_get(void);
-
-void *
-evas_common_language_unicode_funcs_get(void);
-#endif
-