Exactness: add fonts support

One of the biggest issue in Exactness is related to the system
configuration differences. Among them, the fonts can for example
impact on the height of the widgets.
The solution to not be dependent on the fonts consist in using embedded
fonts and to force their usage when playing the applications.

The -f option has been added to the player and the recorder so the user
can provide the path to a fonts directory. This option must be set in
order to force the fonts replacement. Since tests shots can use different
fonts, the exu file stores the version of fonts that have been used.
This is why it is needed to have in the provided directory different
directories, each pointing to a different version of the fonts. For
example, some old tests can use fonts of 2017 (e.g directory 20170101)
while new tests will use new fonts (20180601). Check the
exactness-elm-data repository (fonts branch) for a better understanding.

During recording, the -f option will apply the indicated fonts on the
launched application and will record the mouse events accordingly. The
fonts datestamp is stored in the exu output.
During playing, the fonts will be loaded by reading the exu fonts path,
and then the application is launched. If no information is provided in
the exu but -f is used, the tool will load the most recent fonts (by
comparing the datestamp directories).
master
Daniel Zaoui 4 years ago
parent 621dac67ce
commit 0e1f0cf1c5
  1. 7
      src/bin/exactness.c
  2. 38
      src/bin/inspect.c
  3. 104
      src/bin/player.c
  4. 38
      src/bin/recorder.c
  5. 1
      src/lib/Exactness.h
  6. 1
      src/lib/unit.c

@ -36,7 +36,7 @@ typedef enum
static unsigned short _running_jobs = 0, _max_jobs = 1;
static Eina_List *_base_dirs = NULL;
static char *_dest_dir;
static char *_wrap_command = NULL;
static char *_wrap_command = NULL, *_fonts_dir = NULL;
static int _verbose = 0;
static Eina_Bool _scan_objs = EINA_FALSE;
@ -226,9 +226,10 @@ _run_command_prepare(const List_Entry *ent, char *buf)
ok:
sbuf = eina_strbuf_new();
eina_strbuf_append_printf(sbuf,
"%s %s exactness_play %s %s%.*s %s-t '%s' ",
"%s %s exactness_play %s %s%s %s%.*s %s-t '%s' ",
CONFIG, _wrap_command ? _wrap_command : "",
_mode == RUN_SIMULATION ? "-s" : "",
_fonts_dir ? "-f " : "", _fonts_dir ? _fonts_dir : "",
_verbose ? "-" : "", _verbose, "vvvvvvvvvv",
_scan_objs ? "--scan-objects " : "",
scn_path
@ -458,6 +459,7 @@ static const Ecore_Getopt optdesc = {
ECORE_GETOPT_STORE_TRUE('i', "init", "Run in init mode."),
ECORE_GETOPT_STORE_TRUE('s', "simulation", "Run in simulation mode."),
ECORE_GETOPT_STORE_TRUE(0, "scan-objects", "Extract information of all the objects at every shot."),
ECORE_GETOPT_STORE_STR('f', "fonts-dir", "Specify a directory of the fonts that should be used."),
ECORE_GETOPT_COUNT('v', "verbose", "Turn verbose messages on."),
ECORE_GETOPT_LICENSE('L', "license"),
@ -489,6 +491,7 @@ main(int argc, char *argv[])
ECORE_GETOPT_VALUE_BOOL(mode_init),
ECORE_GETOPT_VALUE_BOOL(mode_simulation),
ECORE_GETOPT_VALUE_BOOL(scan_objs),
ECORE_GETOPT_VALUE_STR(_fonts_dir),
ECORE_GETOPT_VALUE_INT(_verbose),
ECORE_GETOPT_VALUE_BOOL(want_quit),

@ -21,6 +21,7 @@
typedef enum
{
EX_FONTS_DIR,
EX_SCENARIO,
EX_IMAGE,
EX_OBJ_INFO
@ -296,12 +297,37 @@ _grp_text_get(void *data, Evas_Object *gl, const char *part EINA_UNUSED)
_Data_Type dt = (_Data_Type) data;
switch (dt)
{
case EX_FONTS_DIR:
{
char buf2[256];
if (!compare)
{
Exactness_Unit *unit = efl_key_data_get(gl, "unit");
sprintf(buf2, "Fonts directory: %s", unit->fonts_path?unit->fonts_path:"None");
}
else
{
Eo *gl1 = eina_list_nth(_gls, 0);
Eo *gl2 = eina_list_nth(_gls, 1);
Exactness_Unit *unit1 = efl_key_data_get(gl1, "unit");
Exactness_Unit *unit2 = efl_key_data_get(gl2, "unit");
if (!!unit1->fonts_path ^ !!unit2->fonts_path)
sprintf(buf2, "Fonts directory comparison: XXXXX");
else if (!strcmp(unit1->fonts_path, unit2->fonts_path))
sprintf(buf2, "Fonts directory comparison: %s", unit1->fonts_path);
else
sprintf(buf2, "Fonts directory comparison: "LDIFF(%s)"/"RDIFF(%s),
unit1->fonts_path, unit2->fonts_path);
}
return strdup(buf2);
}
case EX_SCENARIO: { str = "Scenario"; break; }
case EX_IMAGE: { str = "Images"; break; }
case EX_OBJ_INFO: { str = "Objects"; break; }
default: { str = "Unknown"; break; }
}
sprintf(buf, "%s%s", str, compare ? " comparison" : "");
if (dt == EX_FONTS_DIR) eina_stringshare_del(str);
return strdup(buf);
}
@ -916,6 +942,17 @@ _gui_unit_display(Exactness_Unit *unit1, Exactness_Unit *unit2)
}
_itc_init();
if (unit1->fonts_path || (unit2 && unit2->fonts_path))
{
if (!_show_only_diffs || !unit1 || !unit2 ||
!unit1->fonts_path || !unit2->fonts_path ||
strcmp(unit1->fonts_path, unit2->fonts_path))
{
elm_genlist_item_append(gl1, _grp_itc, (void *)EX_FONTS_DIR, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
elm_genlist_item_append(gl2, _grp_itc, (void *)EX_FONTS_DIR, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
elm_genlist_item_append(glc, _grp_itc, (void *)EX_FONTS_DIR, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
}
}
itr1 = unit1 ? unit1->actions : NULL;
itr2 = unit2 ? unit2->actions : NULL;
@ -1283,6 +1320,7 @@ main(int argc, char *argv[])
{
Exactness_Action *act;
Eina_List *itr;
if (unit->fonts_path) printf("Fonts dir: %s\n", unit->fonts_path);
EINA_LIST_FOREACH(unit->actions, itr, act)
{
char specific_output[1024];

@ -819,36 +819,32 @@ _prg_invoke(const char *full_path, int argc, char **argv)
return 1;
}
if (_src_open())
if (efl_main)
{
if (efl_main)
{
elm_init(argc, argv);
elm_theme_overlay_add(NULL, DATA_DIR"/exactness_play.edj");
efl_event_callback_add(efl_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL);
ret__ = efl_loop_begin(efl_main_loop_get());
real__ = efl_loop_exit_code_process(ret__);
elm_shutdown();
}
else if (elm_main)
{
elm_init(argc, argv);
elm_theme_overlay_add(NULL, DATA_DIR"/exactness_play.edj");
real__ = elm_main(argc, argv);
elm_shutdown();
}
else if (c_main)
{
real__ = c_main(argc, argv);
}
else
{
fprintf(stderr, "Failed loading symbol 'efl_main', 'elm_main' or 'main' from %s.\n", full_path);
eina_module_free(h);
real__ = 1;
}
elm_init(argc, argv);
elm_theme_overlay_add(NULL, DATA_DIR"/exactness_play.edj");
efl_event_callback_add(efl_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL);
ret__ = efl_loop_begin(efl_main_loop_get());
real__ = efl_loop_exit_code_process(ret__);
elm_shutdown();
}
else if (elm_main)
{
elm_init(argc, argv);
elm_theme_overlay_add(NULL, DATA_DIR"/exactness_play.edj");
real__ = elm_main(argc, argv);
elm_shutdown();
}
else if (c_main)
{
real__ = c_main(argc, argv);
}
else
{
fprintf(stderr, "Failed loading symbol 'efl_main', 'elm_main' or 'main' from %s.\n", full_path);
eina_module_free(h);
real__ = 1;
}
else real__ = 1;
return real__;
}
@ -938,6 +934,7 @@ static const Ecore_Getopt optdesc = {
ECORE_GETOPT_STORE_TRUE(0, "scan-objects", "Extract information of all the objects at every shot."),
ECORE_GETOPT_STORE_TRUE(0, "external-injection", "Expect events injection via Eina debug channel."),
ECORE_GETOPT_STORE_TRUE(0, "disable-screenshots", "Disable screenshots."),
ECORE_GETOPT_STORE_STR('f', "fonts-dir", "Specify a directory of the fonts that should be used."),
ECORE_GETOPT_COUNT('v', "verbose", "Turn verbose messages on."),
ECORE_GETOPT_LICENSE('L', "license"),
@ -952,6 +949,8 @@ int main(int argc, char **argv)
{
int pret = 1, opt_args = 0;
char *src = NULL, *dest = NULL, *eq;
char *fonts_dir = NULL;
const char *chosen_fonts = NULL;
Eina_Bool show_on_screen = EINA_FALSE;
Eina_Bool want_quit = EINA_FALSE, external_injection = EINA_FALSE;
@ -962,6 +961,7 @@ int main(int argc, char **argv)
ECORE_GETOPT_VALUE_BOOL(_scan_objects),
ECORE_GETOPT_VALUE_BOOL(external_injection),
ECORE_GETOPT_VALUE_BOOL(_disable_shots),
ECORE_GETOPT_VALUE_STR(fonts_dir),
ECORE_GETOPT_VALUE_INT(_verbose),
ECORE_GETOPT_VALUE_BOOL(want_quit),
@ -1067,7 +1067,6 @@ int main(int argc, char **argv)
goto end;
}
if (!show_on_screen) setenv("ELM_ENGINE", "buffer", 1);
if (!argv[opt_args])
{
fprintf(stderr, "no program specified\nUse -h for more information\n");
@ -1076,6 +1075,53 @@ int main(int argc, char **argv)
if (_dest_type == FTYPE_EXU) _dest_unit = calloc(1, sizeof(*_dest_unit));
if (!_src_open())
{
fprintf(stderr, "Unable to read source file\n");
goto end;
}
if (!show_on_screen) setenv("ELM_ENGINE", "buffer", 1);
if (_src_unit && _src_unit->fonts_path)
{
char buf[PATH_];
if (!fonts_dir) fonts_dir = "./fonts";
sprintf(buf, "%s/%s", fonts_dir, _src_unit->fonts_path);
if (!ecore_file_exists(buf))
{
fprintf(stderr, "Unable to use the fonts path '%s' provided in %s\n",
_src_unit->fonts_path, _src_filename);
goto end;
}
chosen_fonts = _src_unit->fonts_path;
}
if (fonts_dir)
{
Eina_Tmpstr *fonts_conf_name = NULL;
if (!ecore_file_exists(fonts_dir))
{
fprintf(stderr, "Unable to find fonts directory %s\n", fonts_dir);
goto end;
}
if (!chosen_fonts)
{
Eina_List *dated_fonts = ecore_file_ls(fonts_dir);
char *date_dir;
chosen_fonts = eina_stringshare_add(eina_list_last_data_get(dated_fonts));
EINA_LIST_FREE(dated_fonts, date_dir) free(date_dir);
}
if (chosen_fonts)
{
int tmp_fd = eina_file_mkstemp("/tmp/fonts_XXXXXX.conf", &fonts_conf_name);
dprintf(tmp_fd,
"<?xml version=\"1.0\"?>\n<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n<fontconfig>\n"
"<dir prefix=\"default\">%s/%s</dir>\n</fontconfig>\n",
fonts_dir, chosen_fonts);
close(tmp_fd);
setenv("FONTCONFIG_FILE", fonts_conf_name, 1);
}
}
efl_object_init();
evas_init();

@ -362,6 +362,7 @@ static const Ecore_Getopt optdesc = {
1,
{
ECORE_GETOPT_STORE_STR('t', "test", "Name of the filename where to store the test."),
ECORE_GETOPT_STORE_STR('f', "fonts-dir", "Specify a directory of the fonts that should be used."),
ECORE_GETOPT_COUNT('v', "verbose", "Turn verbose messages on."),
ECORE_GETOPT_LICENSE('L', "license"),
@ -375,11 +376,13 @@ static const Ecore_Getopt optdesc = {
int main(int argc, char **argv)
{
char *dest = NULL, *eq;
char *fonts_dir = NULL;
int pret = 1, opt_args = 0;
Eina_Bool want_quit = EINA_FALSE;
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_STR(dest),
ECORE_GETOPT_VALUE_STR(fonts_dir),
ECORE_GETOPT_VALUE_INT(_verbose),
ECORE_GETOPT_VALUE_BOOL(want_quit),
@ -462,6 +465,36 @@ int main(int argc, char **argv)
efl_object_init();
evas_init();
if (!_unit)
{
_unit = calloc(1, sizeof(*_unit));
}
if (fonts_dir)
{
Eina_Tmpstr *fonts_conf_name = NULL;
if (!ecore_file_exists(fonts_dir))
{
fprintf(stderr, "Unable to find fonts directory %s\n", fonts_dir);
goto end;
}
Eina_List *dated_fonts = ecore_file_ls(fonts_dir);
char *date_dir;
_unit->fonts_path = strdup(eina_list_last_data_get(dated_fonts));
EINA_LIST_FREE(dated_fonts, date_dir) free(date_dir);
if (_unit->fonts_path)
{
int tmp_fd = eina_file_mkstemp("/tmp/fonts_XXXXXX.conf", &fonts_conf_name);
dprintf(tmp_fd,
"<?xml version=\"1.0\"?>\n<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n<fontconfig>\n"
"<dir prefix=\"default\">%s/%s</dir>\n</fontconfig>\n",
fonts_dir, _unit->fonts_path);
close(tmp_fd);
setenv("FONTCONFIG_FILE", fonts_conf_name, 1);
}
}
/* Replace the current command line to hide the Exactness part */
int len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[opt_args];
memcpy(argv[0], argv[opt_args], len);
@ -481,11 +514,6 @@ int main(int argc, char **argv)
if (!_shot_key) _shot_key = getenv("SHOT_KEY");
if (!_shot_key) _shot_key = SHOT_KEY_STR;
if (!_unit)
{
_unit = calloc(1, sizeof(*_unit));
}
ecore_evas_callback_new_set(_my_evas_new);
_last_timestamp = ecore_time_get() * 1000;
pret = _prg_invoke(_prg_full_path_guess(argv[0]), argc - opt_args, argv);

@ -192,6 +192,7 @@ typedef struct
/* imgs not in EET */
Eina_List *imgs; /**< List of Exactness_Image */
Eina_List *objs; /**< List of Exactness_Objects */
const char *fonts_path; /**< Path to the fonts to use, relative to the fonts dir given in parameter to the player/recorder */
int nb_shots; /**< The number of shots present in the unit */
} Exactness_Unit;

@ -243,6 +243,7 @@ _unit_desc_make(void)
unit_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_LIST(unit_d, Exactness_Unit, "actions", actions, action_d);
EET_DATA_DESCRIPTOR_ADD_LIST(unit_d, Exactness_Unit, "objs", objs, objs_d);
EET_DATA_DESCRIPTOR_ADD_BASIC(unit_d, Exactness_Unit, "fonts_path", fonts_path, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(unit_d, Exactness_Unit, "nb_shots", nb_shots, EET_T_UINT);
}

Loading…
Cancel
Save