forked from enlightenment/efl
parent
6c7831c3ab
commit
554dccdb0b
|
@ -189,7 +189,7 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
DATA32 *im;
|
||||
int c;
|
||||
int char_index = 0; /* the index of the current char */
|
||||
|
||||
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
int bidi_err = 0;
|
||||
/*FIXME: should get the direction by parmater */
|
||||
|
@ -223,175 +223,178 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
/* grrr - this means font face sharing is kinda... not an option if */
|
||||
/* you want performance */
|
||||
if ((use_kerning) && (prev_index) && (index) &&
|
||||
(pface == fi->src->ft.face)) {
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
/* if it's rtl, the kerning matching should be reversed, i.e prev
|
||||
* index is now the index and the other way around. */
|
||||
if (evas_intl_is_rtl_char(level_list, char_index)) {
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
(pface == fi->src->ft.face))
|
||||
{
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
/* if it's rtl, the kerning matching should be reversed, i.e prev
|
||||
* index is now the index and the other way around. */
|
||||
if (evas_intl_is_rtl_char(level_list, char_index))
|
||||
{
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
pen_x += kern;
|
||||
{
|
||||
|
||||
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
pen_x += kern;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pface = fi->src->ft.face;
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
if (!fg) continue;
|
||||
pface = fi->src->ft.face;
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
if (!fg) continue;
|
||||
|
||||
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 + (fg->glyph_out->left));
|
||||
chr_y = (pen_y + (fg->glyph_out->top));
|
||||
chr_x = (pen_x + (fg->glyph_out->left));
|
||||
chr_y = (pen_y + (fg->glyph_out->top));
|
||||
|
||||
if (chr_x < (ext_x + ext_w))
|
||||
{
|
||||
DATA8 *data;
|
||||
int i, j, w, h;
|
||||
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
|
||||
{
|
||||
if ((fg->glyph_out->bitmap.num_grays == 256) &&
|
||||
(fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
|
||||
{
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
int dx, dy;
|
||||
int in_x, in_w;
|
||||
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
|
||||
{
|
||||
if ((fg->glyph_out->bitmap.num_grays == 256) &&
|
||||
(fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
|
||||
{
|
||||
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};
|
||||
{
|
||||
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++)
|
||||
{
|
||||
int dx, dy;
|
||||
int in_x, in_w, end;
|
||||
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);
|
||||
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++)
|
||||
{
|
||||
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
|
||||
tp++;
|
||||
}
|
||||
dp++;
|
||||
}
|
||||
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, tmpbuf + in_x, dc->col.col,
|
||||
im + (dy * im_w) + dx, w - in_w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
pen_x += fg->glyph->advance.x >> 16;
|
||||
prev_index = index;
|
||||
{
|
||||
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++)
|
||||
{
|
||||
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
|
||||
tp++;
|
||||
}
|
||||
dp++;
|
||||
}
|
||||
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, tmpbuf + in_x, dc->col.col,
|
||||
im + (dy * im_w) + dx, w - in_w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
pen_x += fg->glyph->advance.x >> 16;
|
||||
prev_index = index;
|
||||
}
|
||||
#ifdef INTERNATIONAL_SUPPORT
|
||||
if (bidi_err >= 0) {
|
||||
free(level_list);
|
||||
free(text);
|
||||
}
|
||||
if (bidi_err >= 0)
|
||||
{
|
||||
free(level_list);
|
||||
free(text);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -401,13 +404,13 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
int ext_x, ext_y, ext_w, ext_h;
|
||||
int im_w, im_h;
|
||||
int use_kerning;
|
||||
RGBA_Gfx_Func func;
|
||||
RGBA_Gfx_Func func;
|
||||
RGBA_Font_Int *fi;
|
||||
Cutout_Rects *rects;
|
||||
Cutout_Rect *r;
|
||||
int c, cx, cy, cw, ch;
|
||||
int i;
|
||||
|
||||
|
||||
fi = fn->fonts->data;
|
||||
|
||||
im_w = dst->cache_entry.w;
|
||||
|
|
|
@ -48,7 +48,7 @@ evas_common_font_ascent_get(RGBA_Font *fn)
|
|||
fi = fn->fonts->data;
|
||||
val = (int)fi->src->ft.face->size->metrics.ascender;
|
||||
if (fi->src->ft.face->units_per_EM == 0)
|
||||
return val;
|
||||
return val;
|
||||
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
|
||||
ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
|
||||
return ret;
|
||||
|
@ -65,7 +65,7 @@ evas_common_font_descent_get(RGBA_Font *fn)
|
|||
fi = fn->fonts->data;
|
||||
val = -(int)fi->src->ft.face->size->metrics.descender;
|
||||
if (fi->src->ft.face->units_per_EM == 0)
|
||||
return val;
|
||||
return val;
|
||||
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
|
||||
ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
|
||||
return ret;
|
||||
|
@ -82,7 +82,7 @@ evas_common_font_max_ascent_get(RGBA_Font *fn)
|
|||
fi = fn->fonts->data;
|
||||
val = (int)fi->src->ft.face->bbox.yMax;
|
||||
if (fi->src->ft.face->units_per_EM == 0)
|
||||
return val;
|
||||
return val;
|
||||
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
|
||||
ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
|
||||
return ret;
|
||||
|
@ -99,7 +99,7 @@ evas_common_font_max_descent_get(RGBA_Font *fn)
|
|||
fi = fn->fonts->data;
|
||||
val = -(int)fi->src->ft.face->bbox.yMin;
|
||||
if (fi->src->ft.face->units_per_EM == 0)
|
||||
return val;
|
||||
return val;
|
||||
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
|
||||
ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
|
||||
return ret;
|
||||
|
@ -116,7 +116,7 @@ evas_common_font_get_line_advance(RGBA_Font *fn)
|
|||
fi = fn->fonts->data;
|
||||
val = (int)fi->src->ft.face->size->metrics.height;
|
||||
if (fi->src->ft.face->units_per_EM == 0)
|
||||
return val;
|
||||
return val;
|
||||
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
|
||||
ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
|
||||
return ret;
|
||||
|
@ -137,11 +137,11 @@ evas_common_font_utf8_get_next(const unsigned char *buf, int *iindex)
|
|||
d = buf[index++];
|
||||
if (!d)
|
||||
return 0;
|
||||
|
||||
|
||||
while (buf[index] && ((buf[index] & 0xc0) == 0x80))
|
||||
index++;
|
||||
len = index - *iindex;
|
||||
|
||||
|
||||
if (len == 1)
|
||||
r = d;
|
||||
else if (len == 2)
|
||||
|
@ -177,7 +177,7 @@ evas_common_font_utf8_get_next(const unsigned char *buf, int *iindex)
|
|||
r <<= 6;
|
||||
r |= (d4 & 0x3f);
|
||||
}
|
||||
|
||||
|
||||
*iindex = index;
|
||||
return r;
|
||||
}
|
||||
|
@ -197,11 +197,11 @@ evas_common_font_utf8_get_prev(const unsigned char *buf, int *iindex)
|
|||
if (index <= 0)
|
||||
return 0;
|
||||
d = buf[index--];
|
||||
|
||||
|
||||
while ((index > 0) && ((buf[index] & 0xc0) == 0x80))
|
||||
index--;
|
||||
len = *iindex - index;
|
||||
|
||||
|
||||
if (len == 1)
|
||||
r = d;
|
||||
else if (len == 2)
|
||||
|
@ -237,7 +237,7 @@ evas_common_font_utf8_get_prev(const unsigned char *buf, int *iindex)
|
|||
r <<= 6;
|
||||
r |= (d4 & 0x3f);
|
||||
}
|
||||
|
||||
|
||||
*iindex = index;
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -146,14 +146,14 @@ evas_common_font_query_inset(RGBA_Font *fn, const char *text)
|
|||
index = evas_common_font_glyph_search(fn, &fi, gl);
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
||||
if (!fg) return 0;
|
||||
/*
|
||||
/*
|
||||
printf("fg->glyph_out->left = %i\n"
|
||||
"fi->src->ft.face->glyph->bitmap_left = %i\n"
|
||||
"fi->src->ft.face->glyph->metrics.horiBearingX = %i\n"
|
||||
"fi->src->ft.face->glyph->metrics.horiBearingY = %i\n"
|
||||
"fi->src->ft.face->glyph->metrics.horiAdvance = %i\n"
|
||||
,
|
||||
(int)fg->glyph_out->left,
|
||||
(int)fg->glyph_out->left,
|
||||
(int)fi->src->ft.face->glyph->bitmap_left,
|
||||
(int)fi->src->ft.face->glyph->metrics.horiBearingX >> 6,
|
||||
(int)fi->src->ft.face->glyph->metrics.horiBearingY >> 6,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Authors:
|
||||
* Tom Hacohen (tom@stsob.com)
|
||||
* Tom Hacohen (tom@stsob.com)
|
||||
*/
|
||||
|
||||
#include "../evas_intl_utils.h"
|
||||
|
@ -73,26 +73,26 @@
|
|||
#define ARABIC_ISOLATED_YODH 0xFEF1
|
||||
|
||||
#define ARABIC_IS_SPECIAL_LETTER(c) ((c) == ARABIC_ISOLATED_ALEPH || \
|
||||
(c) == ARABIC_ISOLATED_DALET || \
|
||||
(c) == ARABIC_ISOLATED_DAL || \
|
||||
(c) == ARABIC_ISOLATED_RESH || \
|
||||
(c) == ARABIC_ISOLATED_ZAYIN || \
|
||||
(c) == ARABIC_ISOLATED_WAW || \
|
||||
(c) == ARABIC_ISOLATED_TA_MARBUTA)
|
||||
(c) == ARABIC_ISOLATED_DALET || \
|
||||
(c) == ARABIC_ISOLATED_DAL || \
|
||||
(c) == ARABIC_ISOLATED_RESH || \
|
||||
(c) == ARABIC_ISOLATED_ZAYIN || \
|
||||
(c) == ARABIC_ISOLATED_WAW || \
|
||||
(c) == ARABIC_ISOLATED_TA_MARBUTA)
|
||||
/* from the first to last (including all forms, and special cases
|
||||
* like aleph maqsura in some forms*/
|
||||
#define ARABIC_IS_CONTEXT(c) (((c) >= ARABIC_ISOLATED_ALEPH && (c) <= ARABIC_ISOLATED_YODH + 3) || \
|
||||
((c) >= ARABIC_ISOLATED_ALEPH_MADDA && (c) <= ARABIC_ISOLATED_ALEPH_MADDA + 3) || \
|
||||
(c) == 0xFBE8 || \
|
||||
(c) == 0xFBE9)
|
||||
((c) >= ARABIC_ISOLATED_ALEPH_MADDA && (c) <= ARABIC_ISOLATED_ALEPH_MADDA + 3) || \
|
||||
(c) == 0xFBE8 || \
|
||||
(c) == 0xFBE9)
|
||||
#define ARABIC_IS_LETTER(c) ARABIC_IS_CONTEXT(c)
|
||||
/* used for arabic context logic */
|
||||
/* each value is the offset from the regular char in unicode */
|
||||
enum _ArabicContext {
|
||||
ARABIC_CONTEXT_ISOLATED = 0,
|
||||
ARABIC_CONTEXT_FINAL = 1,
|
||||
ARABIC_CONTEXT_INITIAL = 2,
|
||||
ARABIC_CONTEXT_MEDIAL = 3
|
||||
ARABIC_CONTEXT_ISOLATED = 0,
|
||||
ARABIC_CONTEXT_FINAL = 1,
|
||||
ARABIC_CONTEXT_INITIAL = 2,
|
||||
ARABIC_CONTEXT_MEDIAL = 3
|
||||
};
|
||||
typedef enum _ArabicContext ArabicContext;
|
||||
|
||||
|
@ -110,73 +110,74 @@ _evas_intl_arabic_general_to_isolated(FriBidiChar chr);
|
|||
int
|
||||
evas_intl_arabic_to_context(FriBidiChar *text)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
int start_of_context = 1; /* assume the first is special/non arabic */
|
||||
int last_is_first = 0;
|
||||
int last_letter = 0;
|
||||
|
||||
/* check for empty string */
|
||||
if (!*text)
|
||||
return;
|
||||
int i;
|
||||
int len;
|
||||
int start_of_context = 1; /* assume the first is special/non arabic */
|
||||
int last_is_first = 0;
|
||||
int last_letter = 0;
|
||||
|
||||
len = _evas_intl_arabic_text_to_isolated(text);
|
||||
/*FIXME: make it skip vowels */
|
||||
for (i = 0 ; i < len ; i++) {
|
||||
/* check for empty string */
|
||||
if (!*text)
|
||||
return;
|
||||
|
||||
if (! ARABIC_IS_LETTER(text[i])) {
|
||||
/* mark so it won't be touched,
|
||||
* though start formating */
|
||||
if (last_letter && !start_of_context) {
|
||||
ArabicContext tmp = (last_is_first) ?
|
||||
ARABIC_CONTEXT_ISOLATED
|
||||
:
|
||||
ARABIC_CONTEXT_FINAL;
|
||||
text[i-1] = _evas_intl_arabic_isolated_to_context(
|
||||
last_letter,
|
||||
tmp);
|
||||
|
||||
}
|
||||
last_is_first = 0;
|
||||
start_of_context = 1;
|
||||
last_letter = 0;
|
||||
continue;
|
||||
}
|
||||
/* adjust the last letter */
|
||||
last_letter = text[i];
|
||||
if (ARABIC_IS_SPECIAL_LETTER(text[i])) {
|
||||
if (!start_of_context)
|
||||
text[i] = _evas_intl_arabic_isolated_to_context(text[i], ARABIC_CONTEXT_FINAL);
|
||||
/* else: leave isolated */
|
||||
|
||||
start_of_context = 1;
|
||||
last_is_first = 0;
|
||||
continue;
|
||||
}
|
||||
len = _evas_intl_arabic_text_to_isolated(text);
|
||||
/*FIXME: make it skip vowels */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (!ARABIC_IS_LETTER(text[i]))
|
||||
{
|
||||
/* mark so it won't be touched,
|
||||
* though start formating */
|
||||
if (last_letter && !start_of_context)
|
||||
{
|
||||
ArabicContext tmp = (last_is_first) ?
|
||||
ARABIC_CONTEXT_ISOLATED : ARABIC_CONTEXT_FINAL;
|
||||
text[i-1] = _evas_intl_arabic_isolated_to_context(
|
||||
last_letter,
|
||||
tmp);
|
||||
}
|
||||
last_is_first = 0;
|
||||
start_of_context = 1;
|
||||
last_letter = 0;
|
||||
continue;
|
||||
}
|
||||
/* adjust the last letter */
|
||||
last_letter = text[i];
|
||||
if (ARABIC_IS_SPECIAL_LETTER(text[i]))
|
||||
{
|
||||
if (!start_of_context)
|
||||
text[i] = _evas_intl_arabic_isolated_to_context(text[i], ARABIC_CONTEXT_FINAL);
|
||||
/* else: leave isolated */
|
||||
|
||||
if (start_of_context) {
|
||||
text[i] = _evas_intl_arabic_isolated_to_context(text[i], ARABIC_CONTEXT_INITIAL);
|
||||
last_is_first = 1;
|
||||
}
|
||||
else {
|
||||
text[i] = _evas_intl_arabic_isolated_to_context(text[i], ARABIC_CONTEXT_MEDIAL);
|
||||
last_is_first = 0;
|
||||
}
|
||||
/* spceial chars don't get here. */
|
||||
start_of_context = 0;
|
||||
|
||||
}
|
||||
/* if it's arabic and not isolated, the last is always final */
|
||||
i--;
|
||||
if (last_letter && !start_of_context) {
|
||||
ArabicContext tmp = (last_is_first) ? ARABIC_CONTEXT_ISOLATED : ARABIC_CONTEXT_FINAL;
|
||||
/* because it's medial atm, and should be isolated */
|
||||
text[i] = _evas_intl_arabic_isolated_to_context(
|
||||
last_letter,
|
||||
tmp);
|
||||
}
|
||||
start_of_context = 1;
|
||||
last_is_first = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
return len;
|
||||
if (start_of_context)
|
||||
{
|
||||
text[i] = _evas_intl_arabic_isolated_to_context(text[i], ARABIC_CONTEXT_INITIAL);
|
||||
last_is_first = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
text[i] = _evas_intl_arabic_isolated_to_context(text[i], ARABIC_CONTEXT_MEDIAL);
|
||||
last_is_first = 0;
|
||||
}
|
||||
/* spceial chars don't get here. */
|
||||
start_of_context = 0;
|
||||
|
||||
}
|
||||
/* if it's arabic and not isolated, the last is always final */
|
||||
i--;
|
||||
if (last_letter && !start_of_context)
|
||||
{
|
||||
ArabicContext tmp = (last_is_first) ? ARABIC_CONTEXT_ISOLATED : ARABIC_CONTEXT_FINAL;
|
||||
/* because it's medial atm, and should be isolated */
|
||||
text[i] = _evas_intl_arabic_isolated_to_context(last_letter, tmp);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* I wish I could think about a simpler way to do it.
|
||||
|
@ -184,131 +185,136 @@ evas_intl_arabic_to_context(FriBidiChar *text)
|
|||
static FriBidiChar
|
||||
_evas_intl_arabic_general_to_isolated(FriBidiChar chr)
|
||||
{
|
||||
switch (chr) {
|
||||
case ARABIC_ALEPH_MADDA:
|
||||
return ARABIC_ISOLATED_ALEPH_MADDA;
|
||||
switch (chr)
|
||||
{
|
||||
case ARABIC_ALEPH_MADDA:
|
||||
return ARABIC_ISOLATED_ALEPH_MADDA;
|
||||
|
||||
case ARABIC_ALEPH:
|
||||
return ARABIC_ISOLATED_ALEPH;
|
||||
case ARABIC_ALEPH:
|
||||
return ARABIC_ISOLATED_ALEPH;
|
||||
|
||||
case ARABIC_TA_MARBUTA:
|
||||
return ARABIC_ISOLATED_TA_MARBUTA;
|
||||
case ARABIC_BET:
|
||||
return ARABIC_ISOLATED_BET;
|
||||
|
||||
case ARABIC_TAW:
|
||||
return ARABIC_ISOLATED_TAW;
|
||||
case ARABIC_TA_MARBUTA:
|
||||
return ARABIC_ISOLATED_TA_MARBUTA;
|
||||
|
||||
case ARABIC_TA:
|
||||
return ARABIC_ISOLATED_TA;
|
||||
|
||||
case ARABIC_GIMEL:
|
||||
return ARABIC_ISOLATED_GIMEL;
|
||||
|
||||
case ARABIC_HETH:
|
||||
return ARABIC_ISOLATED_HETH;
|
||||
|
||||
case ARABIC_HA:
|
||||
return ARABIC_ISOLATED_HA;
|
||||
|
||||
case ARABIC_DALET:
|
||||
return ARABIC_ISOLATED_DALET;
|
||||
|
||||
case ARABIC_DAL:
|
||||
return ARABIC_ISOLATED_DAL;
|
||||
|
||||
case ARABIC_RESH:
|
||||
return ARABIC_ISOLATED_RESH;
|
||||
|
||||
case ARABIC_ZAYIN:
|
||||
return ARABIC_ISOLATED_ZAYIN;
|
||||
|
||||
case ARABIC_SHIN:
|
||||
return ARABIC_ISOLATED_SHIN;
|
||||
|
||||
case ARABIC_SH:
|
||||
return ARABIC_ISOLATED_SH;
|
||||
|
||||
case ARABIC_TSADE:
|
||||
return ARABIC_ISOLATED_TSADE;
|
||||
|
||||
case ARABIC_DAD:
|
||||
return ARABIC_ISOLATED_DAD;
|
||||
|
||||
case ARABIC_TETH:
|
||||
return ARABIC_ISOLATED_TETH;
|
||||
|
||||
case ARABIC_ZA:
|
||||
return ARABIC_ISOLATED_ZA;
|
||||
|
||||
case ARABIC_AYIN:
|
||||
return ARABIC_ISOLATED_AYIN;
|
||||
|
||||
case ARABIC_GHAIN:
|
||||
return ARABIC_ISOLATED_GHAIN;
|
||||
|
||||
case ARABIC_PE:
|
||||
return ARABIC_ISOLATED_PE;
|
||||
|
||||
case ARABIC_QOPH:
|
||||
return ARABIC_ISOLATED_QOPH;
|
||||
|
||||
case ARABIC_KAPH:
|
||||
return ARABIC_ISOLATED_KAPH;
|
||||
|
||||
case ARABIC_LAMED:
|
||||
return ARABIC_ISOLATED_LAMED;
|
||||
case ARABIC_BET:
|
||||
return ARABIC_ISOLATED_BET;
|
||||
|
||||
case ARABIC_MEM:
|
||||
return ARABIC_ISOLATED_MEM;
|
||||
|
||||
case ARABIC_NUN:
|
||||
return ARABIC_ISOLATED_NUN;
|
||||
|
||||
case ARABIC_HE:
|
||||
return ARABIC_ISOLATED_HE;
|
||||
|
||||
case ARABIC_WAW:
|
||||
return ARABIC_ISOLATED_WAW;
|
||||
case ARABIC_TAW:
|
||||
return ARABIC_ISOLATED_TAW;
|
||||
|
||||
case ARABIC_ALEPH_MAQSURA:
|
||||
return ARABIC_ISOLATED_ALEPH_MAQSURA;
|
||||
|
||||
case ARABIC_YODH:
|
||||
return ARABIC_ISOLATED_YODH;
|
||||
default:
|
||||
return chr;
|
||||
}
|
||||
case ARABIC_TA:
|
||||
return ARABIC_ISOLATED_TA;
|
||||
|
||||
case ARABIC_GIMEL:
|
||||
return ARABIC_ISOLATED_GIMEL;
|
||||
|
||||
case ARABIC_HETH:
|
||||
return ARABIC_ISOLATED_HETH;
|
||||
|
||||
case ARABIC_HA:
|
||||
return ARABIC_ISOLATED_HA;
|
||||
|
||||
case ARABIC_DALET:
|
||||
return ARABIC_ISOLATED_DALET;
|
||||
|
||||
case ARABIC_DAL:
|
||||
return ARABIC_ISOLATED_DAL;
|
||||
|
||||
case ARABIC_RESH:
|
||||
return ARABIC_ISOLATED_RESH;
|
||||
|
||||
case ARABIC_ZAYIN:
|
||||
return ARABIC_ISOLATED_ZAYIN;
|
||||
|
||||
case ARABIC_SHIN:
|
||||
return ARABIC_ISOLATED_SHIN;
|
||||
|
||||
case ARABIC_SH:
|
||||
return ARABIC_ISOLATED_SH;
|
||||
|
||||
case ARABIC_TSADE:
|
||||
return ARABIC_ISOLATED_TSADE;
|
||||
|
||||
case ARABIC_DAD:
|
||||
return ARABIC_ISOLATED_DAD;
|
||||
|
||||
case ARABIC_TETH:
|
||||
return ARABIC_ISOLATED_TETH;
|
||||
|
||||
case ARABIC_ZA:
|
||||
return ARABIC_ISOLATED_ZA;
|
||||
|
||||
case ARABIC_AYIN:
|
||||
return ARABIC_ISOLATED_AYIN;
|
||||
|
||||
case ARABIC_GHAIN:
|
||||
return ARABIC_ISOLATED_GHAIN;
|
||||
|
||||
case ARABIC_PE:
|
||||
return ARABIC_ISOLATED_PE;
|
||||
|
||||
case ARABIC_QOPH:
|
||||
return ARABIC_ISOLATED_QOPH;
|
||||
|
||||
case ARABIC_KAPH:
|
||||
return ARABIC_ISOLATED_KAPH;
|
||||
|
||||
case ARABIC_LAMED:
|
||||
return ARABIC_ISOLATED_LAMED;
|
||||
|
||||
case ARABIC_MEM:
|
||||
return ARABIC_ISOLATED_MEM;
|
||||
|
||||
case ARABIC_NUN:
|
||||
return ARABIC_ISOLATED_NUN;
|
||||
|
||||
case ARABIC_HE:
|
||||
return ARABIC_ISOLATED_HE;
|
||||
|
||||
case ARABIC_WAW:
|
||||
return ARABIC_ISOLATED_WAW;
|
||||
|
||||
case ARABIC_ALEPH_MAQSURA:
|
||||
return ARABIC_ISOLATED_ALEPH_MAQSURA;
|
||||
|
||||
case ARABIC_YODH:
|
||||
return ARABIC_ISOLATED_YODH;
|
||||
default:
|
||||
return chr;
|
||||
}
|
||||
}
|
||||
|
||||
static FriBidiChar
|
||||
_evas_intl_arabic_isolated_to_context(FriBidiChar chr, ArabicContext context)
|
||||
{
|
||||
if (ARABIC_IS_SPECIAL_LETTER(chr)) {
|
||||
if (context == ARABIC_CONTEXT_INITIAL)
|
||||
return chr;
|
||||
else
|
||||
return chr + ARABIC_CONTEXT_FINAL;
|
||||
}
|
||||
/* HACK AROUND ALIF MAQSURA */
|
||||
else if (chr == ARABIC_ISOLATED_ALEPH_MAQSURA && context > 1) {
|
||||
chr = 0xFBE8; /* the initial form */
|
||||
context -= 2;
|
||||
}
|
||||
return chr + context;
|
||||
if (ARABIC_IS_SPECIAL_LETTER(chr))
|
||||
{
|
||||
if (context == ARABIC_CONTEXT_INITIAL)
|
||||
return chr;
|
||||
else
|
||||
return chr + ARABIC_CONTEXT_FINAL;
|
||||
}
|
||||
/* HACK AROUND ALIF MAQSURA */
|
||||
else if (chr == ARABIC_ISOLATED_ALEPH_MAQSURA && context > 1)
|
||||
{
|
||||
chr = 0xFBE8; /* the initial form */
|
||||
context -= 2;
|
||||
}
|
||||
return chr + context;
|
||||
}
|
||||
|
||||
static int
|
||||
_evas_intl_arabic_text_to_isolated(FriBidiChar *text)
|
||||
{
|
||||
int i=0;
|
||||
while (*text) {
|
||||
/* if it's not arabic/it's already in context
|
||||
* it's just returned the same */
|
||||
*text = _evas_intl_arabic_general_to_isolated(*text);
|
||||
text++;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
int i = 0;
|
||||
while (*text)
|
||||
{
|
||||
/* if it's not arabic/it's already in context
|
||||
* it's just returned the same */
|
||||
*text = _evas_intl_arabic_general_to_isolated(*text);
|
||||
text++;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Authors:
|
||||
* Tom Hacohen (tom@stsob.com)
|
||||
* Tom Hacohen (tom@stsob.com)
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -14,96 +14,96 @@
|
|||
|
||||
/* FIXME: fribidi_utf8_to_unicode should use char len and not byte len!*/
|
||||
char *
|
||||
evas_intl_utf8_to_visual(const char *text, int *ret_len, FriBidiCharType *direction,
|
||||
FriBidiLevel **embedding_level_list)
|
||||
evas_intl_utf8_to_visual(const char *text, int *ret_len, FriBidiCharType *direction, FriBidiLevel **embedding_level_list)
|
||||
{
|
||||
FriBidiChar *unicode_in, *unicode_out;
|
||||
char *text_out;
|
||||
size_t len;
|
||||
size_t byte_len;
|
||||
FriBidiChar *unicode_in, *unicode_out;
|
||||
char *text_out;
|
||||
size_t len;
|
||||
size_t byte_len;
|
||||
|
||||
if (!text)
|
||||
return NULL;
|
||||
if (!text)
|
||||
return NULL;
|
||||
|
||||
len = evas_string_char_len_get(text);
|
||||
len = evas_string_char_len_get(text);
|
||||
|
||||
/* if there's nothing to do, return text
|
||||
* one char draws are quite common */
|
||||
if (len <= 1) {
|
||||
*ret_len = len;
|
||||
*embedding_level_list = NULL;
|
||||
return strdup(text);
|
||||
}
|
||||
|
||||
byte_len = strlen(text); /* we need the actual number of bytes, not number of chars */
|
||||
|
||||
unicode_in=(FriBidiChar *)malloc(sizeof(FriBidiChar)*(len+1));
|
||||
if (!unicode_in) {
|
||||
len = -1;
|
||||
goto error1;
|
||||
|
||||
}
|
||||
|
||||
len = fribidi_utf8_to_unicode(text, byte_len, unicode_in);
|
||||
|
||||
unicode_out=(FriBidiChar *)malloc(sizeof(FriBidiChar)*(len+1));
|
||||
if (!unicode_out) {
|
||||
len = -2;
|
||||
goto error2;
|
||||
|
||||
}
|
||||
/* if there's nothing to do, return text
|
||||
* one char draws are quite common */
|
||||
if (len <= 1)
|
||||
{
|
||||
*ret_len = len;
|
||||
*embedding_level_list = NULL;
|
||||
return strdup(text);
|
||||
}
|
||||
|
||||
*embedding_level_list=(FriBidiLevel *)malloc(sizeof(FriBidiLevel)*len);
|
||||
if (!*embedding_level_list) {
|
||||
len = -3;
|
||||
goto error3;
|
||||
|
||||
}
|
||||
byte_len = strlen(text); /* we need the actual number of bytes, not number of chars */
|
||||
|
||||
unicode_in = (FriBidiChar *)malloc(sizeof(FriBidiChar) * (len + 1));
|
||||
if (!unicode_in)
|
||||
{
|
||||
len = -1;
|
||||
goto error1;
|
||||
}
|
||||
|
||||
len = fribidi_utf8_to_unicode(text, byte_len, unicode_in);
|
||||
|
||||
unicode_out = (FriBidiChar *)malloc(sizeof(FriBidiChar) * (len + 1));
|
||||
if (!unicode_out)
|
||||
{
|
||||
len = -2;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
*embedding_level_list = (FriBidiLevel *)malloc(sizeof(FriBidiLevel) * len);
|
||||
if (!*embedding_level_list)
|
||||
{
|
||||
len = -3;
|
||||
goto error3;
|
||||
}
|
||||
|
||||
#ifdef ARABIC_SUPPORT
|
||||
/* fix arabic context */
|
||||
evas_intl_arabic_to_context(unicode_in);
|
||||
#endif
|
||||
if (! fribidi_log2vis(unicode_in, len, direction,
|
||||
unicode_out, NULL, NULL, *embedding_level_list)) {
|
||||
len = -4;
|
||||
goto error3;
|
||||
|
||||
}
|
||||
/* fix arabic context */
|
||||
evas_intl_arabic_to_context(unicode_in);
|
||||
#endif
|
||||
if (!fribidi_log2vis(unicode_in, len, direction,
|
||||
unicode_out, NULL, NULL, *embedding_level_list))
|
||||
{
|
||||
len = -4;
|
||||
goto error3;
|
||||
}
|
||||
|
||||
text_out = malloc(UTF8_BYTES_PER_CHAR * len + 1);
|
||||
if (!text_out) {
|
||||
len = -5;
|
||||
goto error4;
|
||||
}
|
||||
text_out = malloc(UTF8_BYTES_PER_CHAR * len + 1);
|
||||
if (!text_out)
|
||||
{
|
||||
len = -5;
|
||||
goto error4;
|
||||
}
|
||||
|
||||
fribidi_unicode_to_utf8(unicode_out, len, text_out);
|
||||
|
||||
free(unicode_in);
|
||||
free(unicode_out);
|
||||
fribidi_unicode_to_utf8(unicode_out, len, text_out);
|
||||
|
||||
*ret_len = len;
|
||||
return text_out;
|
||||
free(unicode_in);
|
||||
free(unicode_out);
|
||||
|
||||
/* ERROR HANDLING */
|
||||
*ret_len = len;
|
||||
return text_out;
|
||||
|
||||
/* ERROR HANDLING */
|
||||
error4:
|
||||
free(unicode_out);
|
||||
free(unicode_out);
|
||||
error3:
|
||||
free(*embedding_level_list);
|
||||
free(*embedding_level_list);
|
||||
error2:
|
||||
free(unicode_in);
|
||||
free(unicode_in);
|
||||
error1:
|
||||
|
||||
*ret_len = len;
|
||||
return NULL;
|
||||
*ret_len = len;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
evas_intl_is_rtl_char(FriBidiLevel *embedded_level_list, FriBidiStrIndex i)
|
||||
{
|
||||
if(embedded_level_list || i < 0)
|
||||
return 0;
|
||||
return FRIBIDI_IS_RTL(embedded_level_list[i]);
|
||||
if(embedded_level_list || i < 0)
|
||||
return 0;
|
||||
return FRIBIDI_IS_RTL(embedded_level_list[i]);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,8 +22,7 @@ int
|
|||
evas_intl_is_rtl_char(FriBidiLevel *embedded_level_list, FriBidiStrIndex i);
|
||||
|
||||
char *
|
||||
evas_intl_utf8_to_visual(const char *text, int *ret_len, FriBidiCharType *direction,
|
||||
FriBidiLevel **embedding_level_list);
|
||||
evas_intl_utf8_to_visual(const char *text, int *ret_len, FriBidiCharType *direction, FriBidiLevel **embedding_level_list);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue