<commit_before>#include "evas_common.h"
#include "evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */
#include "evas_font_private.h" /* for Frame-Queuing support */

EAPI int
evas_common_font_query_kerning(RGBA_Font_Int* fi,
			       FT_UInt left, FT_UInt right,
			       int* kerning)
{
   int *result;
   FT_Vector delta;
   int key[2];
   int error = 1;

//   return 0;
   key[0] = left;
   key[1] = right;

   result = eina_hash_find(fi->kerning, key);
   if (result)
     {
	*kerning = result[2];
	goto on_correct;
     }

   /* NOTE: ft2 seems to have a bug. and sometimes returns bizarre
    * values to kern by - given same font, same size and same
    * prev_index and index. auto/bytecode or none hinting doesn't
    * matter */
   evas_common_font_int_reload(fi);
   FTLOCK();
   if (FT_Get_Kerning(fi->src->ft.face,
		      key[0], key[1],
		      ft_kerning_default, &delta) == 0)
     {
	int *push;

        FTUNLOCK();
	*kerning = delta.x >> 6;

	push = malloc(sizeof (int) * 3);
	if (!push) return 1;

	push[0] = key[0];
	push[1] = key[1];
	push[2] = *kerning;

	eina_hash_direct_add(fi->kerning, push, push);

	goto on_correct;
     }

        FTUNLOCK();
   error = 0;

 on_correct:
   return error;
}

/* text x inset */
EAPI int
evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text)
{
   FT_UInt index;
   RGBA_Font_Glyph *fg;
   int gl;
   RGBA_Font_Int *fi;

   fi = fn->fonts->data;

   if (!*text) return 0;
   gl = *text;
   if (gl == 0) return 0;
//   evas_common_font_size_use(fn);
   index = evas_common_font_glyph_search(fn, &fi, gl);
   LKL(fi->ft_mutex);
   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;
     }
   fg = evas_common_font_int_cache_glyph_get(fi, index);
   LKU(fi->ft_mutex);
   if (!fg) return 0;
/*
   INF("fg->glyph_out->left = %i, "
	  "fi->src->ft.face->glyph->bitmap_left = %i, "
	  "fi->src->ft.face->glyph->metrics.horiBearingX = %i, "
	  "fi->src->ft.face->glyph->metrics.horiBearingY = %i, "
	  "fi->src->ft.face->glyph->metrics.horiAdvance = %i"
	  ,
	  (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,
	  (int)fi->src->ft.face->glyph->metrics.horiAdvance >> 6
	  );
 */
  evas_common_font_int_use_trim();
  return fg->glyph_out->left;
}

/**
 * @def _INIT_FI_AND_KERNINNG()
 * @internal
 * This macro inits fi and use_kerning.
 * Assumes the following variables exist:
 * fi, fn and use_kerning.
 */
#define _INIT_FI_AND_KERNING() \
   do \
     { \
        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; \
          } \
        FTLOCK(); \
        use_kerning = FT_HAS_KERNING(fi->src->ft.face); \
        FTUNLOCK(); \
     } \
   while (0)

/* size of the string (width and height) in pixels
 * BiDi handling: We receive the shaped string + other props from intl_props,
 * We only care about the size, and the size does not depend on the visual order.
 * As long as we follow the logical string and get kerning data like we should,
 * we are fine.
 */

EAPI void
evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props __UNUSED__, int *w, int *h)
{
   int keep_width;
   int use_kerning;
   RGBA_Font_Int *fi;
   EVAS_FONT_WALK_TEXT_INIT();
   _INIT_FI_AND_KERNING();

   EVAS_FONT_WALK_TEXT_START()
     {
        EVAS_FONT_WALK_TEXT_WORK();
        /* Keep the width because we'll need it for the last char */
        keep_width = width;
     }
   EVAS_FONT_WALK_TEXT_END();
   if (w) *w = pen_x + keep_width;
   if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn);
  evas_common_font_int_use_trim();
}
}

/* h & v advance
 * BiDi handling: We receive the shaped string + other props from intl_props,
 * We don't care about the order, as heights will remain the same (we already did
 * shaping) and as long as we go through the logical string and match the kerning
 * this way, we are safe.
 */
EAPI void
evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *h_adv, int *v_adv)
{
   int keep_adv;
   int use_kerning;
   RGBA_Font_Int *fi;
   EVAS_FONT_WALK_TEXT_INIT();
   _INIT_FI_AND_KERNING();

   EVAS_FONT_WALK_TEXT_START()
     {
        EVAS_FONT_WALK_TEXT_WORK();
        /* Keep the advancement because we want to also do the last
         * advancement */
        keep_adv = adv;
     }
   EVAS_FONT_WALK_TEXT_END();

   if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
   if (h_adv) *h_adv = pen_x + keep_adv;
  evas_common_font_int_use_trim();
}<commit_msg>Evas font engine: Fixed query_size and query advance.<commit_after>#include "evas_common.h"
#include "evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */
#include "evas_font_private.h" /* for Frame-Queuing support */

EAPI int
evas_common_font_query_kerning(RGBA_Font_Int* fi,
			       FT_UInt left, FT_UInt right,
			       int* kerning)
{
   int *result;
   FT_Vector delta;
   int key[2];
   int error = 1;

//   return 0;
   key[0] = left;
   key[1] = right;

   result = eina_hash_find(fi->kerning, key);
   if (result)
     {
	*kerning = result[2];
	goto on_correct;
     }

   /* NOTE: ft2 seems to have a bug. and sometimes returns bizarre
    * values to kern by - given same font, same size and same
    * prev_index and index. auto/bytecode or none hinting doesn't
    * matter */
   evas_common_font_int_reload(fi);
   FTLOCK();
   if (FT_Get_Kerning(fi->src->ft.face,
		      key[0], key[1],
		      ft_kerning_default, &delta) == 0)
     {
	int *push;

        FTUNLOCK();
	*kerning = delta.x >> 6;

	push = malloc(sizeof (int) * 3);
	if (!push) return 1;

	push[0] = key[0];
	push[1] = key[1];
	push[2] = *kerning;

	eina_hash_direct_add(fi->kerning, push, push);

	goto on_correct;
     }

        FTUNLOCK();
   error = 0;

 on_correct:
   return error;
}

/* text x inset */
EAPI int
evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text)
{
   FT_UInt index;
   RGBA_Font_Glyph *fg;
   int gl;
   RGBA_Font_Int *fi;

   fi = fn->fonts->data;

   if (!*text) return 0;
   gl = *text;
   if (gl == 0) return 0;
//   evas_common_font_size_use(fn);
   index = evas_common_font_glyph_search(fn, &fi, gl);
   LKL(fi->ft_mutex);
   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;
     }
   fg = evas_common_font_int_cache_glyph_get(fi, index);
   LKU(fi->ft_mutex);
   if (!fg) return 0;
/*
   INF("fg->glyph_out->left = %i, "
	  "fi->src->ft.face->glyph->bitmap_left = %i, "
	  "fi->src->ft.face->glyph->metrics.horiBearingX = %i, "
	  "fi->src->ft.face->glyph->metrics.horiBearingY = %i, "
	  "fi->src->ft.face->glyph->metrics.horiAdvance = %i"
	  ,
	  (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,
	  (int)fi->src->ft.face->glyph->metrics.horiAdvance >> 6
	  );
 */
  evas_common_font_int_use_trim();
  return fg->glyph_out->left;
}

/**
 * @def _INIT_FI_AND_KERNINNG()
 * @internal
 * This macro inits fi and use_kerning.
 * Assumes the following variables exist:
 * fi, fn and use_kerning.
 */
#define _INIT_FI_AND_KERNING() \
   do \
     { \
        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; \
          } \
        FTLOCK(); \
        use_kerning = FT_HAS_KERNING(fi->src->ft.face); \
        FTUNLOCK(); \
     } \
   while (0)

/* size of the string (width and height) in pixels
 * BiDi handling: We receive the shaped string + other props from intl_props,
 * We only care about the size, and the size does not depend on the visual order.
 * As long as we follow the logical string and get kerning data like we should,
 * we are fine.
 */

EAPI void
evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props __UNUSED__, int *w, int *h)
{
   int keep_width = 0;
   int use_kerning;
   RGBA_Font_Int *fi;
   EVAS_FONT_WALK_TEXT_INIT();
   _INIT_FI_AND_KERNING();

   EVAS_FONT_WALK_TEXT_START()
     {
        EVAS_FONT_WALK_TEXT_WORK();
        /* Keep the width because we'll need it for the last char */
        keep_width = width + bear_x;
     }
   EVAS_FONT_WALK_TEXT_END();
   if (w) *w = pen_x + keep_width;
   if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn);
  evas_common_font_int_use_trim();
}
}

/* h & v advance
 * BiDi handling: We receive the shaped string + other props from intl_props,
 * We don't care about the order, as heights will remain the same (we already did
 * shaping) and as long as we go through the logical string and match the kerning
 * this way, we are safe.
 */
EAPI void
evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *h_adv, int *v_adv)
{
   int keep_adv = 0;
   int use_kerning;
   RGBA_Font_Int *fi;
   EVAS_FONT_WALK_TEXT_INIT();
   _INIT_FI_AND_KERNING();

   EVAS_FONT_WALK_TEXT_START()
     {
        EVAS_FONT_WALK_TEXT_WORK();
        /* Keep the advancement because we want to also do the last
         * advancement */
        keep_adv = adv;
     }
   EVAS_FONT_WALK_TEXT_END();

   if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
   if (h_adv) *h_adv = pen_x + keep_adv;
  evas_common_font_int_use_trim();
}
{'fraction_non_alphanumeric': 0.1318864774624374, 'fraction_numerical': 0.0054993616812334285, 'mean_word_length': 2.967276977015972, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 147, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2480496', 'n_tokens_mistral': 4055, 'n_tokens_neox': 3862, 'n_words': 878}