forked from enlightenment/efl
Evas font-engine: Cache pen position instead of advance.
We only really use adavnce for calculating the pen position, so it makes more sense to just cache the pen_position instead and calculate advance from that if ever needed. This means size/advance calculations are now O(1) because we don't need to walk the strings anymore. SVN revision: 58756
This commit is contained in:
parent
2f86580227
commit
543c0cafc0
|
@ -13,6 +13,9 @@
|
|||
*/
|
||||
# define EVAS_FONT_WALK_TEXT_INIT() \
|
||||
int _pen_x = 0, _pen_y = 0; \
|
||||
Evas_Coord _start_pen = (text_props->info && \
|
||||
(text_props->start > 0)) ? \
|
||||
text_props->info->glyph[text_props -> start - 1].pen_after : 0 ; \
|
||||
size_t char_index; \
|
||||
(void) _pen_y; /* Sometimes it won't be used */
|
||||
|
||||
|
@ -149,13 +152,14 @@
|
|||
#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_X_ADV ((_glyph_itr > text_props->info->glyph) ? \
|
||||
_glyph_itr->pen_after - (_glyph_itr - 1)->pen_after : \
|
||||
_glyph_itr->pen_after)
|
||||
#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_X (_pen_x)
|
||||
#define EVAS_FONT_WALK_PEN_X_AFTER (_glyph_itr->pen_after - _start_pen)
|
||||
#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 \
|
||||
|
@ -186,7 +190,7 @@
|
|||
#define EVAS_FONT_WALK_TEXT_END() \
|
||||
if (EVAS_FONT_WALK_IS_VISIBLE) \
|
||||
{ \
|
||||
_pen_x += _EVAS_FONT_WALK_X_ADV; \
|
||||
_pen_x = _glyph_itr->pen_after - _start_pen; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
|
|
|
@ -196,6 +196,7 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
|
|||
unsigned int i;
|
||||
Evas_Font_Glyph_Info *gl_itr;
|
||||
Evas_Font_OT_Info *ot_itr;
|
||||
Evas_Coord pen_x = 0;
|
||||
|
||||
fi = fn->fonts->data;
|
||||
/* Load the font needed for this script */
|
||||
|
@ -252,11 +253,15 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
|
|||
ot_itr = props->info->ot;
|
||||
for (i = 0 ; i < props->len ; i++)
|
||||
{
|
||||
Evas_Coord adv;
|
||||
ot_itr->source_cluster = infos->cluster;
|
||||
ot_itr->x_offset = positions->x_offset;
|
||||
ot_itr->y_offset = positions->y_offset;
|
||||
gl_itr->index = infos->codepoint;
|
||||
gl_itr->advance = positions->x_advance;
|
||||
adv = positions->x_advance;
|
||||
|
||||
pen_x += adv;
|
||||
gl_itr->pen_after = EVAS_FONT_ROUND_26_6_TO_INT(pen_x);
|
||||
|
||||
ot_itr++;
|
||||
gl_itr++;
|
||||
|
|
|
@ -79,10 +79,12 @@ evas_common_font_query_right_inset(RGBA_Font *fn __UNUSED__, const Evas_Text_Pro
|
|||
if (gli->width == 0)
|
||||
return 0;
|
||||
|
||||
return EVAS_FONT_ROUND_26_6_TO_INT(gli->advance) -
|
||||
return ((gli > text_props->info->glyph) ?
|
||||
gli->pen_after - (gli - 1)->pen_after : gli->pen_after) -
|
||||
(gli->width + gli->x_bear
|
||||
#ifdef OT_SUPPORT
|
||||
+ text_props->info->ot[text_props->start + text_props->len - 1].x_offset
|
||||
+ EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(
|
||||
text_props->info->ot[text_props->start + text_props->len - 1]))
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
@ -97,32 +99,29 @@ evas_common_font_query_right_inset(RGBA_Font *fn __UNUSED__, const Evas_Text_Pro
|
|||
EAPI void
|
||||
evas_common_font_query_size(RGBA_Font *fn, const Evas_Text_Props *text_props, int *w, int *h)
|
||||
{
|
||||
int keep_width = 0;
|
||||
int prev_pen_x = 0;
|
||||
EVAS_FONT_WALK_TEXT_INIT();
|
||||
Evas_Coord ret_w = 0;
|
||||
|
||||
EVAS_FONT_WALK_TEXT_VISUAL_START()
|
||||
if (text_props->len > 0)
|
||||
{
|
||||
EVAS_FONT_WALK_TEXT_WORK();
|
||||
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
|
||||
/* Keep the width because we'll need it for the last char */
|
||||
keep_width = EVAS_FONT_WALK_WIDTH +
|
||||
EVAS_FONT_WALK_X_OFF +
|
||||
EVAS_FONT_WALK_X_BEAR;
|
||||
/* Keep the previous EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */
|
||||
prev_pen_x = EVAS_FONT_WALK_PEN_X;
|
||||
}
|
||||
EVAS_FONT_WALK_TEXT_END();
|
||||
const Evas_Font_Glyph_Info *glyph = text_props->info->glyph +
|
||||
text_props->start;
|
||||
const Evas_Font_Glyph_Info *last_glyph = glyph;
|
||||
|
||||
/* If the last char is a whitespace, we use the advance as the size */
|
||||
if (keep_width > 0)
|
||||
{
|
||||
if (w) *w = prev_pen_x + keep_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (w) *w = EVAS_FONT_WALK_PEN_X;
|
||||
if (text_props->len > 1)
|
||||
{
|
||||
last_glyph += text_props->len - 1;
|
||||
ret_w = last_glyph[-1].pen_after;
|
||||
if (text_props->start > 0)
|
||||
ret_w -= glyph[-1].pen_after;
|
||||
}
|
||||
#ifdef OT_SUPPORT
|
||||
ret_w += EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(
|
||||
text_props->info->ot[text_props->start + text_props->len - 1]));
|
||||
#endif
|
||||
ret_w += last_glyph->width + last_glyph->x_bear;
|
||||
}
|
||||
|
||||
if (w) *w = ret_w;
|
||||
if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn);
|
||||
}
|
||||
|
||||
|
@ -135,17 +134,18 @@ evas_common_font_query_size(RGBA_Font *fn, const Evas_Text_Props *text_props, in
|
|||
EAPI void
|
||||
evas_common_font_query_advance(RGBA_Font *fn, const Evas_Text_Props *text_props, int *h_adv, int *v_adv)
|
||||
{
|
||||
EVAS_FONT_WALK_TEXT_INIT();
|
||||
|
||||
EVAS_FONT_WALK_TEXT_LOGICAL_START()
|
||||
Evas_Coord ret_adv = 0;
|
||||
if (text_props->len > 0)
|
||||
{
|
||||
EVAS_FONT_WALK_TEXT_WORK();
|
||||
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
|
||||
const Evas_Font_Glyph_Info *glyph = text_props->info->glyph +
|
||||
text_props->start;
|
||||
ret_adv = glyph[text_props->len - 1].pen_after;
|
||||
if (text_props->start > 0)
|
||||
ret_adv -= glyph[-1].pen_after;
|
||||
}
|
||||
EVAS_FONT_WALK_TEXT_END();
|
||||
|
||||
if (h_adv) *h_adv = ret_adv;
|
||||
if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
|
||||
if (h_adv) *h_adv = EVAS_FONT_WALK_PEN_X;
|
||||
}
|
||||
|
||||
/* x y w h for char at char pos for null it returns the position right after
|
||||
|
@ -430,8 +430,8 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Evas_Text_Props *text
|
|||
/* we need to see if the char at the visual position is the char,
|
||||
* we check that by checking if it's before the current pen
|
||||
* position and the next */
|
||||
if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_ADV)) &&
|
||||
(y >= -asc) && (y <= desc))
|
||||
if ((x >= EVAS_FONT_WALK_PEN_X) &&
|
||||
(x <= (EVAS_FONT_WALK_PEN_X_AFTER)) && (y >= -asc) && (y <= desc))
|
||||
{
|
||||
#ifdef OT_SUPPORT
|
||||
items = evas_common_font_ot_cluster_size_get(text_props,
|
||||
|
@ -496,8 +496,8 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props *text
|
|||
EVAS_FONT_WALK_TEXT_WORK();
|
||||
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
|
||||
|
||||
if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_ADV)) &&
|
||||
(y >= -asc) && (y <= desc))
|
||||
if ((x >= EVAS_FONT_WALK_PEN_X) &&
|
||||
(x <= (EVAS_FONT_WALK_PEN_X_AFTER)) && (y >= -asc) && (y <= desc))
|
||||
{
|
||||
ret = EVAS_FONT_WALK_POS;
|
||||
goto end;
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
#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)
|
||||
|
@ -207,6 +204,7 @@ evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
|
|||
size_t char_index;
|
||||
Evas_Font_Glyph_Info *gl_itr;
|
||||
const Eina_Unicode *base_char;
|
||||
Evas_Coord pen_x = 0, adjust_x = 0;
|
||||
(void) par_props;
|
||||
(void) par_pos;
|
||||
|
||||
|
@ -248,14 +246,7 @@ evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
|
|||
continue;
|
||||
}
|
||||
LKU(fi->ft_mutex);
|
||||
if (is_replacement)
|
||||
{
|
||||
/* Update the advance accordingly */
|
||||
gl_itr->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);
|
||||
}
|
||||
|
||||
gl_itr->x_bear = fg->glyph_out->left;
|
||||
gl_itr->width = fg->glyph_out->bitmap.width;
|
||||
/* text_props->info->glyph[char_index].advance =
|
||||
|
@ -263,7 +254,32 @@ evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
|
|||
* already done by the ot function */
|
||||
if (EVAS_FONT_CHARACTER_IS_INVISIBLE(
|
||||
text[text_props->info->ot[char_index].source_cluster]))
|
||||
gl_itr->index = 0;
|
||||
{
|
||||
gl_itr->index = 0;
|
||||
/* Reduce the current advance */
|
||||
if (gl_itr > text_props->info->glyph)
|
||||
{
|
||||
adjust_x -= gl_itr->pen_after - (gl_itr - 1)->pen_after;
|
||||
}
|
||||
else
|
||||
{
|
||||
adjust_x -= gl_itr->pen_after;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_replacement)
|
||||
{
|
||||
/* Update the advance accordingly */
|
||||
adjust_x += (pen_x + (fg->glyph->advance.x >> 16)) -
|
||||
gl_itr->pen_after;
|
||||
|
||||
/* FIXME: reload fi, a bit slow, but I have no choice. */
|
||||
evas_common_font_glyph_search(fn, &fi, *base_char);
|
||||
}
|
||||
pen_x = gl_itr->pen_after;
|
||||
}
|
||||
gl_itr->pen_after += adjust_x;
|
||||
|
||||
gl_itr++;
|
||||
}
|
||||
|
@ -273,6 +289,7 @@ evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
|
|||
Eina_Bool use_kerning;
|
||||
FT_UInt prev_index;
|
||||
FT_Face pface = NULL;
|
||||
Evas_Coord pen_x = 0;
|
||||
int adv_d, i;
|
||||
#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
|
||||
text = text_props->info->shaped_text = eina_unicode_strndup(text, len);
|
||||
|
@ -308,6 +325,7 @@ evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
|
|||
FT_UInt index;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int _gl, kern;
|
||||
Evas_Coord adv;
|
||||
_gl = *text;
|
||||
if (_gl == 0) break;
|
||||
|
||||
|
@ -351,7 +369,7 @@ evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
|
|||
{
|
||||
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
|
||||
{
|
||||
(gl_itr - 1)->advance += kern;
|
||||
(gl_itr - 1)->pen_after += kern;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -359,7 +377,7 @@ evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
|
|||
{
|
||||
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
||||
{
|
||||
(gl_itr - 1)->advance += kern;
|
||||
(gl_itr - 1)->pen_after += kern;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -367,14 +385,22 @@ evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
|
|||
pface = fi->src->ft.face;
|
||||
LKU(fi->ft_mutex);
|
||||
|
||||
if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl))
|
||||
gl_itr->index = 0;
|
||||
|
||||
gl_itr->index = index;
|
||||
gl_itr->x_bear = fg->glyph_out->left;
|
||||
gl_itr->advance = fg->glyph->advance.x >> 10;
|
||||
adv = fg->glyph->advance.x >> 10;
|
||||
gl_itr->width = fg->glyph_out->bitmap.width;
|
||||
|
||||
if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl))
|
||||
{
|
||||
gl_itr->index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pen_x += adv;
|
||||
}
|
||||
|
||||
gl_itr->pen_after = EVAS_FONT_ROUND_26_6_TO_INT(pen_x);
|
||||
|
||||
prev_index = index;
|
||||
}
|
||||
text_props->len = len;
|
||||
|
|
|
@ -9,6 +9,9 @@ typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info;
|
|||
# include "language/evas_bidi_utils.h"
|
||||
# include "language/evas_language_utils.h"
|
||||
|
||||
/* Used for showing "malformed" or missing chars */
|
||||
#define REPLACEMENT_CHAR 0xFFFD
|
||||
|
||||
struct _Evas_Text_Props
|
||||
{
|
||||
/* Start and len represent the start offset and the length in the
|
||||
|
@ -44,7 +47,7 @@ struct _Evas_Font_Glyph_Info
|
|||
Evas_Coord y_bear;
|
||||
#endif
|
||||
Evas_Coord width;
|
||||
Evas_Coord advance;
|
||||
Evas_Coord pen_after;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue