*/
# 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 */
#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 \
#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; \
} \
} \
} \
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 */
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++;
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
);
}
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);
}
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
/* 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,
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;
#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)
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;
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 =
* 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++;
}
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);
FT_UInt index;
RGBA_Font_Glyph *fg;
int _gl, kern;
+ Evas_Coord adv;
_gl = *text;
if (_gl == 0) break;
{
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
{
- (gl_itr - 1)->advance += kern;
+ (gl_itr - 1)->pen_after += kern;
}
}
else
{
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
{
- (gl_itr - 1)->advance += kern;
+ (gl_itr - 1)->pen_after += kern;
}
}
}
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;
# 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
Evas_Coord y_bear;
#endif
Evas_Coord width;
- Evas_Coord advance;
+ Evas_Coord pen_after;
};