Evas font-engine: pen_x is now calculated with fractional pixels (inside each item, not the case with cross-items which still use integral pixels).

SVN revision: 56509
This commit is contained in:
Tom Hacohen 2011-01-30 10:42:13 +00:00
parent 99c8c7bb2f
commit f7dfb4d8fb
5 changed files with 53 additions and 46 deletions

View File

@ -21,12 +21,12 @@
visible && !is_visual) \ visible && !is_visual) \
{ \ { \
if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \ if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \
pen_x += kern; \ _pen_x += kern; \
} \ } \
else \ else \
{ \ { \
if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \ if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \
pen_x += kern; \ _pen_x += kern; \
} \ } \
} \ } \
while (0) while (0)
@ -36,7 +36,7 @@
{ \ { \
(void) is_visual; \ (void) is_visual; \
if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \ if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \
pen_x += kern; \ _pen_x += kern; \
} \ } \
while (0) while (0)
#endif #endif
@ -113,7 +113,9 @@
#define EVAS_FONT_WALK_DEFAULT_Y_OFF (0) #define EVAS_FONT_WALK_DEFAULT_Y_OFF (0)
#define EVAS_FONT_WALK_DEFAULT_X_BEAR (fg->glyph_out->left) #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_Y_BEAR (fg->glyph_out->top)
#define EVAS_FONT_WALK_DEFAULT_X_ADV (fg->glyph->advance.x >> 16) #define _EVAS_FONT_WALK_DEFAULT_X_ADV (fg->glyph->advance.x >> 10)
#define EVAS_FONT_WALK_DEFAULT_X_ADV \
(EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_DEFAULT_X_ADV))
#define EVAS_FONT_WALK_DEFAULT_Y_ADV (0) #define EVAS_FONT_WALK_DEFAULT_Y_ADV (0)
#define EVAS_FONT_WALK_DEFAULT_WIDTH (fg->glyph_out->bitmap.width) #define EVAS_FONT_WALK_DEFAULT_WIDTH (fg->glyph_out->bitmap.width)
#define EVAS_FONT_WALK_DEFAULT_POS (char_index) #define EVAS_FONT_WALK_DEFAULT_POS (char_index)
@ -182,7 +184,7 @@
#define EVAS_FONT_WALK_DEFAULT_TEXT_END() \ #define EVAS_FONT_WALK_DEFAULT_TEXT_END() \
if (visible) \ if (visible) \
{ \ { \
pen_x += EVAS_FONT_WALK_DEFAULT_X_ADV; \ _pen_x += _EVAS_FONT_WALK_DEFAULT_X_ADV; \
} \ } \
prev_index = index; \ prev_index = index; \
} \ } \

View File

@ -504,8 +504,8 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
} }
pen_x = x; /*FIXME: Handle it sanely */
pen_y = y; _pen_y = y;
im = dst->image.data; im = dst->image.data;
#ifdef OT_SUPPORT #ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled() && intl_props->ot_data) if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
@ -523,8 +523,8 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
fg->ext_dat_free = dc->font_ext.func.gl_free; fg->ext_dat_free = dc->font_ext.func.gl_free;
} }
chr_x = (pen_x) + EVAS_FONT_WALK_OT_X_OFF + EVAS_FONT_WALK_OT_X_BEAR; chr_x = x + EVAS_FONT_WALK_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_y = (_pen_y) + EVAS_FONT_WALK_OT_Y_OFF + EVAS_FONT_WALK_OT_Y_BEAR;
chr_w = EVAS_FONT_WALK_OT_WIDTH; chr_w = EVAS_FONT_WALK_OT_WIDTH;
if (chr_x < (ext_x + ext_w)) if (chr_x < (ext_x + ext_w))
@ -672,8 +672,8 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
fg->ext_dat_free = dc->font_ext.func.gl_free; 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_x = x + EVAS_FONT_WALK_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_y = (_pen_y) + EVAS_FONT_WALK_DEFAULT_Y_OFF + EVAS_FONT_WALK_DEFAULT_Y_BEAR;
chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH; chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH;
if (chr_x < (ext_x + ext_w)) if (chr_x < (ext_x + ext_w))
@ -969,16 +969,16 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Eva
ci->fg->glyph->advance.x >> 16 > 0) ci->fg->glyph->advance.x >> 16 > 0)
{ {
if (evas_common_font_query_kerning(fi, ci->index, prev_index, &kern)) if (evas_common_font_query_kerning(fi, ci->index, prev_index, &kern))
pen_x += kern; pen_x += EVAS_FONT_ROUND_26_6_TO_INT(kern);
} }
else else
{ {
if (evas_common_font_query_kerning(fi, prev_index, ci->index, &kern)) if (evas_common_font_query_kerning(fi, prev_index, ci->index, &kern))
pen_x += kern; pen_x += EVAS_FONT_ROUND_26_6_TO_INT(kern);
} }
# else # else
if (evas_common_font_query_kerning(fi, prev_index, ci->index, &kern)) if (evas_common_font_query_kerning(fi, prev_index, ci->index, &kern))
pen_x += kern; pen_x += EVAS_FONT_ROUND_26_6_TO_INT(kern);
# endif # endif
} }

View File

@ -99,10 +99,11 @@
intl_props->ot_data->items[char_index]))) intl_props->ot_data->items[char_index])))
#define EVAS_FONT_WALK_OT_X_BEAR (fg->glyph_out->left) #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_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]))
#define EVAS_FONT_WALK_OT_X_ADV \ #define EVAS_FONT_WALK_OT_X_ADV \
(EVAS_FONT_ROUND_26_6_TO_INT( \ (EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_OT_X_ADV))
EVAS_FONT_OT_X_ADV_GET( \
intl_props->ot_data->items[char_index])))
#define EVAS_FONT_WALK_OT_WIDTH (fg->glyph_out->bitmap.width) #define EVAS_FONT_WALK_OT_WIDTH (fg->glyph_out->bitmap.width)
#define EVAS_FONT_WALK_OT_POS \ #define EVAS_FONT_WALK_OT_POS \
(EVAS_FONT_OT_POS_GET( \ (EVAS_FONT_OT_POS_GET( \
@ -165,7 +166,7 @@
#define EVAS_FONT_WALK_OT_TEXT_END() \ #define EVAS_FONT_WALK_OT_TEXT_END() \
if (visible) \ if (visible) \
{ \ { \
pen_x += EVAS_FONT_WALK_OT_X_ADV; \ _pen_x += _EVAS_FONT_WALK_OT_X_ADV; \
} \ } \
prev_index = index; \ prev_index = index; \
} \ } \

View File

@ -37,8 +37,9 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi);
# define OTUNLOCK() # define OTUNLOCK()
# endif # endif
/* 6th bit is on is the same as frac part >= 0.5 */
# define EVAS_FONT_ROUND_26_6_TO_INT(x) \ # define EVAS_FONT_ROUND_26_6_TO_INT(x) \
(((0x3F & x) > 31) ? ((x >> 6) + 1) : (x >> 6)) ((0x20 & x) ? ((x >> 6) + 1) : (x >> 6))
# define EVAS_FONT_CHARACTER_IS_INVISIBLE(x) ( \ # define EVAS_FONT_CHARACTER_IS_INVISIBLE(x) ( \
((0x200C <= (x)) && ((x) <= 0x200D)) || /* ZWNJ..ZWH */ \ ((0x200C <= (x)) && ((x) <= 0x200D)) || /* ZWNJ..ZWH */ \
@ -64,12 +65,14 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi);
* @see EVAS_FONT_WALK_TEXT_END * @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 _pen_x = 0, _pen_y = 0; \
size_t char_index; \ size_t char_index; \
FT_UInt prev_index; \ FT_UInt prev_index; \
FT_Face pface = NULL; \ FT_Face pface = NULL; \
int _len = eina_unicode_strlen(text); \ int _len = eina_unicode_strlen(text); \
(void) _len; /* We don't have to use it */ \ (void) _len; /* We don't have to use it */ \
(void) pen_y; /* Sometimes it won't be used */ (void) _pen_y; /* Sometimes it won't be used */
# define EVAS_FONT_WALK_PEN_X (EVAS_FONT_ROUND_26_6_TO_INT(_pen_x))
#endif /* !_EVAS_FONT_PRIVATE_H */ #endif /* !_EVAS_FONT_PRIVATE_H */

View File

@ -36,7 +36,7 @@ evas_common_font_query_kerning(RGBA_Font_Int* fi,
int *push; int *push;
FTUNLOCK(); FTUNLOCK();
*kerning = delta.x >> 6; *kerning = delta.x;
push = malloc(sizeof (int) * 3); push = malloc(sizeof (int) * 3);
if (!push) return 1; if (!push) return 1;
@ -157,8 +157,8 @@ evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_
/* Keep the width because we'll need it for the last char */ /* 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 + keep_width = EVAS_FONT_WALK_OT_WIDTH + EVAS_FONT_WALK_OT_X_OFF +
EVAS_FONT_WALK_OT_X_BEAR; EVAS_FONT_WALK_OT_X_BEAR;
/* Keep the previous pen_x, before it's advanced in TEXT_END */ /* Keep the previous EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */
prev_pen_x = pen_x; prev_pen_x = EVAS_FONT_WALK_PEN_X;
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_OT_TEXT_END();
} }
@ -173,8 +173,8 @@ evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_
keep_width = EVAS_FONT_WALK_DEFAULT_WIDTH + keep_width = EVAS_FONT_WALK_DEFAULT_WIDTH +
EVAS_FONT_WALK_DEFAULT_X_OFF + EVAS_FONT_WALK_DEFAULT_X_OFF +
EVAS_FONT_WALK_DEFAULT_X_BEAR; EVAS_FONT_WALK_DEFAULT_X_BEAR;
/* Keep the previous pen_x, before it's advanced in TEXT_END */ /* Keep the previous EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */
prev_pen_x = pen_x; prev_pen_x = EVAS_FONT_WALK_PEN_X;
} }
EVAS_FONT_WALK_DEFAULT_TEXT_END(); EVAS_FONT_WALK_DEFAULT_TEXT_END();
} }
@ -223,7 +223,7 @@ evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Ev
} }
if (v_adv) *v_adv = evas_common_font_get_line_advance(fn); if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
if (h_adv) *h_adv = pen_x; if (h_adv) *h_adv = EVAS_FONT_WALK_PEN_X;
evas_common_font_int_use_trim(); evas_common_font_int_use_trim();
} }
@ -294,12 +294,13 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
} }
else else
{ {
cluster_start = (pen_x) + EVAS_FONT_WALK_OT_X_OFF + cluster_start = EVAS_FONT_WALK_PEN_X +
EVAS_FONT_WALK_OT_X_OFF +
EVAS_FONT_WALK_OT_X_BEAR; EVAS_FONT_WALK_OT_X_BEAR;
} }
} }
last_is_visible = visible; last_is_visible = visible;
last_end = pen_x + EVAS_FONT_WALK_OT_X_OFF + last_end = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_OFF +
EVAS_FONT_WALK_OT_X_BEAR + EVAS_FONT_WALK_OT_WIDTH; EVAS_FONT_WALK_OT_X_BEAR + EVAS_FONT_WALK_OT_WIDTH;
/* we need to see if the char at the visual position is the char wanted */ /* we need to see if the char at the visual position is the char wanted */
if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) && if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
@ -358,13 +359,13 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE); EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
if (visible) if (visible)
{ {
chr_x = (pen_x) + EVAS_FONT_WALK_DEFAULT_X_OFF + chr_x = (EVAS_FONT_WALK_PEN_X) + EVAS_FONT_WALK_DEFAULT_X_OFF +
EVAS_FONT_WALK_DEFAULT_X_BEAR; EVAS_FONT_WALK_DEFAULT_X_BEAR;
chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH; chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH;
} }
else else
{ {
chr_x = pen_x; chr_x = EVAS_FONT_WALK_PEN_X;
chr_w = 0; chr_w = 0;
} }
/* we need to see if the char at the visual position is the char wanted */ /* we need to see if the char at the visual position is the char wanted */
@ -453,7 +454,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
} }
else else
{ {
cluster_start = pen_x; cluster_start = EVAS_FONT_WALK_PEN_X;
} }
} }
last_is_visible = visible; last_is_visible = visible;
@ -486,7 +487,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
if (found) if (found)
{ {
Evas_Coord cluster_adv; Evas_Coord cluster_adv;
cluster_adv = pen_x - cluster_start; cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
if (cy) *cy = -asc; if (cy) *cy = -asc;
if (ch) *ch = asc + desc; if (ch) *ch = asc + desc;
if (last_is_visible) if (last_is_visible)
@ -498,7 +499,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
} }
else else
{ {
if (cpen_x) *cpen_x = pen_x; if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
if (cadv) *cadv = 0; if (cadv) *cadv = 0;
} }
ret_val = 1; ret_val = 1;
@ -522,12 +523,12 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
{ {
if (EVAS_FONT_WALK_DEFAULT_X_ADV > 0) if (EVAS_FONT_WALK_DEFAULT_X_ADV > 0)
{ {
if (cpen_x) *cpen_x = pen_x; if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_X_ADV; if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_X_ADV;
} }
else else
{ {
if (cpen_x) *cpen_x = pen_x + if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X +
EVAS_FONT_WALK_DEFAULT_X_OFF + EVAS_FONT_WALK_DEFAULT_X_OFF +
EVAS_FONT_WALK_DEFAULT_X_BEAR; EVAS_FONT_WALK_DEFAULT_X_BEAR;
if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_WIDTH; if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_WIDTH;
@ -535,7 +536,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
} }
else else
{ {
if (cpen_x) *cpen_x = pen_x; if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
if (cadv) *cadv = 0; if (cadv) *cadv = 0;
} }
ret_val = 1; ret_val = 1;
@ -590,7 +591,7 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
} }
else else
{ {
cluster_start = pen_x; cluster_start = EVAS_FONT_WALK_PEN_X;
} }
} }
@ -599,7 +600,7 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
/* we need to see if the char at the visual position is the char, /* 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 * we check that by checking if it's before the current pen
* position and the next */ * position and the next */
if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_OT_X_ADV)) && if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_ADV)) &&
(y >= -asc) && (y <= desc)) (y >= -asc) && (y <= desc))
{ {
items = evas_common_font_ot_cluster_size_get(intl_props, items = evas_common_font_ot_cluster_size_get(intl_props,
@ -614,7 +615,7 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
{ {
int item_pos; int item_pos;
Evas_Coord cluster_adv; Evas_Coord cluster_adv;
cluster_adv = pen_x - cluster_start; cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR)
{ {
@ -628,7 +629,7 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
part = cluster_adv / items; part = cluster_adv / items;
item_pos = items - ((int) ((x - cluster_start) / part)) - 1; item_pos = items - ((int) ((x - cluster_start) / part)) - 1;
} }
if (cx) *cx = pen_x + if (cx) *cx = EVAS_FONT_WALK_PEN_X +
((cluster_adv / items) * (item_pos - 1)); ((cluster_adv / items) * (item_pos - 1));
if (cy) *cy = -asc; if (cy) *cy = -asc;
if (cw) *cw = (cluster_adv / items); if (cw) *cw = (cluster_adv / items);
@ -648,10 +649,10 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
/* we need to see if the char at the visual position is the char, /* 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 * we check that by checking if it's before the current pen position
* and the next */ * and the next */
if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_DEFAULT_X_ADV)) if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_ADV))
&& (y >= -asc) && (y <= desc)) && (y >= -asc) && (y <= desc))
{ {
if (cx) *cx = pen_x + EVAS_FONT_WALK_DEFAULT_X_OFF + if (cx) *cx = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_OFF +
EVAS_FONT_WALK_DEFAULT_X_BEAR + EVAS_FONT_WALK_DEFAULT_X_BEAR +
EVAS_FONT_WALK_DEFAULT_X_ADV; EVAS_FONT_WALK_DEFAULT_X_ADV;
if (cy) *cy = -asc; if (cy) *cy = -asc;
@ -699,7 +700,7 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
if (!visible) continue; if (!visible) continue;
if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_OT_X_ADV)) && if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_ADV)) &&
(y >= -asc) && (y <= desc)) (y >= -asc) && (y <= desc))
{ {
ret = EVAS_FONT_WALK_OT_POS; ret = EVAS_FONT_WALK_OT_POS;
@ -716,8 +717,8 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE); EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
if (!visible) continue; if (!visible) continue;
if ((x >= pen_x) && if ((x >= EVAS_FONT_WALK_PEN_X) &&
(x <= (pen_x + EVAS_FONT_WALK_DEFAULT_X_ADV)) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_ADV)) &&
(y >= -asc) && (y <= desc)) (y >= -asc) && (y <= desc))
{ {
ret = char_index; ret = char_index;