Merge branch 'master' into releases/1.8

This commit is contained in:
Daniel Eklöf 2021-07-01 20:13:49 +02:00
commit fd974e139e
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
24 changed files with 1509 additions and 193 deletions

View file

@ -1,5 +1,6 @@
# Changelog
* [Unreleased](#unreleased)
* [1.8.0](#1-8-0)
* [1.7.2](#1-7-2)
* [1.7.1](#1-7-1)
@ -26,6 +27,40 @@
* [1.2.0](#1-2-0)
## Unreleased
### Added
* `--log-level=none` command-line option.
* `Tc`, `setrgbf` and `setrgbb` capabilities in `foot` and `foot-direct`
terminfo entries. This should make 24-bit RGB colors work in tmux and
neovim, without the need for config hacks or detection heuristics
(https://codeberg.org/dnkl/foot/issues/615).
### Changed
* Grapheme cluster width is now limited to two cells by default. This
may cause cursor synchronization issues with many applications. You
can set `[tweak].grapheme-width-method=wcswidth` to revert to the
behavior from foot-1.8.0.
### Deprecated
### Removed
### Fixed
* Grapheme cluster state being reset between codepoints.
* Regression: custom URL key bindings not working
(https://codeberg.org/dnkl/foot/issues/614).
### Security
### Contributors
* [craigbarnes](https://codeberg.org/craigbarnes)
## 1.8.0
### Grapheme shaping

View file

@ -58,22 +58,22 @@ print_usage(const char *prog_name)
printf("Usage: %s [OPTIONS...] command [ARGS...]\n", prog_name);
printf("\n");
printf("Options:\n");
printf(" -t,--term=TERM value to set the environment variable TERM to (foot)\n"
" -T,--title=TITLE initial window title (foot)\n"
" -a,--app-id=ID window application ID (foot)\n"
" -w,--window-size-pixels=WIDTHxHEIGHT initial width and height, in pixels\n"
" -W,--window-size-chars=WIDTHxHEIGHT initial width and height, in characters\n"
" -m,--maximized start in maximized mode\n"
" -F,--fullscreen start in fullscreen mode\n"
" -L,--login-shell start shell as a login shell\n"
" -D,--working-directory=DIR directory to start in (CWD)\n"
" -s,--server-socket=PATH path to the server UNIX domain socket (default=$XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock)\n"
" -H,--hold remain open after child process exits\n"
" -N,--no-wait detach the client process from the running terminal, exiting immediately\n"
" -o,--override=[section.]key=value override configuration option\n"
" -d,--log-level={info|warning|error} log level (info)\n"
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
" -v,--version show the version number and quit\n");
printf(" -t,--term=TERM value to set the environment variable TERM to (foot)\n"
" -T,--title=TITLE initial window title (foot)\n"
" -a,--app-id=ID window application ID (foot)\n"
" -w,--window-size-pixels=WIDTHxHEIGHT initial width and height, in pixels\n"
" -W,--window-size-chars=WIDTHxHEIGHT initial width and height, in characters\n"
" -m,--maximized start in maximized mode\n"
" -F,--fullscreen start in fullscreen mode\n"
" -L,--login-shell start shell as a login shell\n"
" -D,--working-directory=DIR directory to start in (CWD)\n"
" -s,--server-socket=PATH path to the server UNIX domain socket (default=$XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock)\n"
" -H,--hold remain open after child process exits\n"
" -N,--no-wait detach the client process from the running terminal, exiting immediately\n"
" -o,--override=[section.]key=value override configuration option\n"
" -d,--log-level={info|warning|error|none} log level (info)\n"
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
" -v,--version show the version number and quit\n");
}
static bool NOINLINE

View file

@ -68,7 +68,7 @@ _foot()
which fc-list > /dev/null || return 1
COMPREPLY=( $(compgen -W "$(fc-list : family | sed 's/,/\n/g' | uniq | tr -d ' ')" -- ${cur}) )
elif [[ ${prev} == '--log-level' ]] ; then
COMPREPLY=( $(compgen -W "error warning info" -- ${cur}) )
COMPREPLY=( $(compgen -W "none error warning info" -- ${cur}) )
elif [[ ${prev} == '--log-colorize' ]] ; then
COMPREPLY=( $(compgen -W "never always auto" -- ${cur}) )
elif [[ ${prev} =~ ^(--app-id|--help|--override|--title|--version|--window-size-chars|--window-size-pixels|--check-config)$ ]] ; then

View file

@ -59,7 +59,7 @@ _footclient()
which toe > /dev/null || return 1
COMPREPLY=( $(compgen -W "$(toe -a | awk '$1 ~ /[+]/ {next}; {print $1}')" -- ${cur}) )
elif [[ ${prev} == '--log-level' ]] ; then
COMPREPLY=( $(compgen -W "error warning info" -- ${cur}) )
COMPREPLY=( $(compgen -W "none error warning info" -- ${cur}) )
elif [[ ${prev} == '--log-colorize' ]] ; then
COMPREPLY=( $(compgen -W "never always auto" -- ${cur}) )
elif [[ ${prev} =~ ^(--app-id|--help|--override|--title|--version|--window-size-chars|--window-size-pixels|)$ ]] ; then

View file

@ -15,7 +15,7 @@ complete -c foot -x -s W -l window-size-chars
complete -c foot -F -s s -l server -d "run as server; open terminals by running footclient"
complete -c foot -s H -l hold -d "remain open after child process exits"
complete -c foot -r -s p -l print-pid -d "print PID to this file or FD when up and running (server mode only)"
complete -c foot -x -s d -l log-level -a "info warning error" -d "log-level (info)"
complete -c foot -x -s d -l log-level -a "info warning error none" -d "log-level (info)"
complete -c foot -x -s l -l log-colorize -a "always never auto" -d "enable or disable colorization of log output on stderr"
complete -c foot -s S -l log-no-syslog -d "disable syslog logging (server mode only)"
complete -c foot -s v -l version -d "show the version number and quit"

View file

@ -12,7 +12,7 @@ complete -c footclient -F -s s -l server-socket
complete -c footclient -s H -l hold -d "remain open after child process exits"
complete -c footclient -s N -l no-wait -d "detach the client process from the running terminal, exiting immediately"
complete -c footclient -x -s o -l override -d "configuration option to override, in form SECTION.KEY=VALUE"
complete -c footclient -x -s d -l log-level -a "info warning error" -d "log-level (info)"
complete -c footclient -x -s d -l log-level -a "info warning error none" -d "log-level (info)"
complete -c footclient -x -s l -l log-colorize -a "always never auto" -d "enable or disable colorization of log output on stderr"
complete -c footclient -s v -l version -d "show the version number and quit"
complete -c footclient -s h -l help -d "show help message and quit"

View file

@ -18,7 +18,7 @@ _arguments \
'(-s --server)'{-s,--server}'[run as server; open terminals by running footclient]:server:_files' \
'(-H --hold)'{-H,--hold}'[remain open after child process exits]' \
'(-p --print-pid)'{-p,--print-pid}'[print PID to this file or FD when up and running (server mode only)]:pidfile:_files' \
'(-d --log-level)'{-d,--log-level}'[log level (info)]:loglevel:(info warning error)' \
'(-d --log-level)'{-d,--log-level}'[log level (info)]:loglevel:(info warning error none)' \
'(-l --log-colorize)'{-l,--log-colorize}'[enable or disable colorization of log output on stderr]:logcolor:(never always auto)' \
'(-S --log-no-syslog)'{-s,--log-no-syslog}'[disable syslog logging (server mode only)]' \
'(-v --version)'{-v,--version}'[show the version number and quit]' \

View file

@ -15,7 +15,7 @@ _arguments \
'(-H --hold)'{-H,--hold}'[remain open after child process exits]' \
'(-N --no-wait)'{-N,--no-wait}'[detach the client process from the running terminal, exiting immediately]' \
'(-o --override)'{-o,--override}'[configuration option to override, in form SECTION.KEY=VALUE]:()' \
'(-d --log-level)'{-d,--log-level}'[log level (info)]:loglevel:(info warning error)' \
'(-d --log-level)'{-d,--log-level}'[log level (info)]:loglevel:(info warning error none)' \
'(-l --log-colorize)'{-l,--log-colorize}'[enable or disable colorization of log output on stderr]:logcolor:(never always auto)' \
'(-v --version)'{-v,--version}'[show the version number and quit]' \
'(-h --help)'{-h,--help}'[show help message and quit]' \

201
config.c
View file

@ -103,8 +103,10 @@ log_and_notify(struct config *conf, enum log_class log_class,
case LOG_CLASS_INFO:
case LOG_CLASS_DEBUG:
BUG("unsupported log class: %d", log_class);
break;
case LOG_CLASS_NONE:
default:
BUG("unsupported log class: %d", (int)log_class);
return;
}
va_list va1, va2;
@ -191,7 +193,7 @@ struct path_component {
};
typedef tll(struct path_component) path_components_t;
static void
static void NOINLINE
path_component_add(path_components_t *components, const char *comp, int fd)
{
xassert(comp != NULL);
@ -201,14 +203,14 @@ path_component_add(path_components_t *components, const char *comp, int fd)
tll_push_back(*components, pc);
}
static void
static void NOINLINE
path_component_destroy(struct path_component *component)
{
xassert(component->fd >= 0);
close(component->fd);
}
static void
static void NOINLINE
path_components_destroy(path_components_t *components)
{
tll_foreach(*components, it) {
@ -1660,6 +1662,43 @@ pipe_argv_from_string(const char *value, char ***argv,
return remove_len;
}
static void NOINLINE
remove_action_from_key_bindings_list(struct config_key_binding_list *bindings,
int action, char **pipe_argv)
{
size_t remove_first_idx = 0;
size_t remove_count = 0;
for (size_t i = 0; i < bindings->count; i++) {
struct config_key_binding *binding = &bindings->arr[i];
if (binding->action == action &&
((binding->pipe.argv.args == NULL && pipe_argv == NULL) ||
(binding->pipe.argv.args != NULL && pipe_argv != NULL &&
argv_compare(binding->pipe.argv.args, pipe_argv) == 0)))
{
if (remove_count++ == 0)
remove_first_idx = i;
xassert(remove_first_idx + remove_count - 1 == i);
if (binding->pipe.master_copy)
free_argv(&binding->pipe.argv);
}
}
if (remove_count == 0)
return;
size_t move_count = bindings->count - (remove_first_idx + remove_count);
memmove(
&bindings->arr[remove_first_idx],
&bindings->arr[remove_first_idx + remove_count],
move_count * sizeof(bindings->arr[0]));
bindings->count -= remove_count;
}
static bool NOINLINE
parse_key_binding_section(
const char *section, const char *key, const char *value,
@ -1686,17 +1725,7 @@ parse_key_binding_section(
/* Unset binding */
if (strcasecmp(value, "none") == 0) {
for (size_t i = 0; i < bindings->count; i++) {
struct config_key_binding *binding = &bindings->arr[i];
if (binding->action != action)
continue;
if (binding->pipe.master_copy)
free_argv(&binding->pipe.argv);
binding->action = BIND_ACTION_NONE;
}
remove_action_from_key_bindings_list(bindings, action, pipe_argv);
free(pipe_argv);
return true;
}
@ -1713,21 +1742,7 @@ parse_key_binding_section(
return false;
}
/* Remove existing bindings for this action+pipe */
for (size_t i = 0; i < bindings->count; i++) {
struct config_key_binding *binding = &bindings->arr[i];
if (binding->action == action &&
((binding->pipe.argv.args == NULL && pipe_argv == NULL) ||
(binding->pipe.argv.args != NULL && pipe_argv != NULL &&
argv_compare(binding->pipe.argv.args, pipe_argv) == 0)))
{
if (binding->pipe.master_copy)
free_argv(&binding->pipe.argv);
binding->action = BIND_ACTION_NONE;
}
}
remove_action_from_key_bindings_list(bindings, action, pipe_argv);
/* Emit key bindings */
size_t ofs = bindings->count;
@ -1765,6 +1780,90 @@ parse_key_binding_section(
return false;
}
UNITTEST
{
enum test_actions {
TEST_ACTION_NONE,
TEST_ACTION_FOO,
TEST_ACTION_BAR,
TEST_ACTION_COUNT,
};
const char *const map[] = {
[TEST_ACTION_NONE] = NULL,
[TEST_ACTION_FOO] = "foo",
[TEST_ACTION_BAR] = "bar",
};
struct config conf = {0};
struct config_key_binding_list bindings = {0};
/*
* ADD foo=Escape
*
* This verifies we can bind a single key combo to an action.
*/
xassert(parse_key_binding_section(
"", "foo", "Escape", ALEN(map), map, &bindings, &conf, "", 0));
xassert(bindings.count == 1);
xassert(bindings.arr[0].action == TEST_ACTION_FOO);
xassert(bindings.arr[0].sym == XKB_KEY_Escape);
/*
* ADD bar=Control+g Control+Shift+x
*
* This verifies we can bind multiple key combos to an action.
*/
xassert(parse_key_binding_section(
"", "bar", "Control+g Control+Shift+x", ALEN(map), map,
&bindings, &conf, "", 0));
xassert(bindings.count == 3);
xassert(bindings.arr[0].action == TEST_ACTION_FOO);
xassert(bindings.arr[1].action == TEST_ACTION_BAR);
xassert(bindings.arr[1].sym == XKB_KEY_g);
xassert(bindings.arr[1].modifiers.ctrl);
xassert(bindings.arr[2].action == TEST_ACTION_BAR);
xassert(bindings.arr[2].sym == XKB_KEY_x);
xassert(bindings.arr[2].modifiers.ctrl && bindings.arr[2].modifiers.shift);
/*
* REPLACE foo with foo=Mod+v Shift+q
*
* This verifies we can update a single-combo action with multiple
* key combos.
*/
xassert(parse_key_binding_section(
"", "foo", "Mod1+v Shift+q", ALEN(map), map,
&bindings, &conf, "", 0));
xassert(bindings.count == 4);
xassert(bindings.arr[0].action == TEST_ACTION_BAR);
xassert(bindings.arr[1].action == TEST_ACTION_BAR);
xassert(bindings.arr[2].action == TEST_ACTION_FOO);
xassert(bindings.arr[2].sym == XKB_KEY_v);
xassert(bindings.arr[2].modifiers.alt);
xassert(bindings.arr[3].action == TEST_ACTION_FOO);
xassert(bindings.arr[3].sym == XKB_KEY_q);
xassert(bindings.arr[3].modifiers.shift);
/*
* REMOVE bar
*/
xassert(parse_key_binding_section(
"", "bar", "none", ALEN(map), map, &bindings, &conf, "", 0));
xassert(bindings.count == 2);
xassert(bindings.arr[0].action == TEST_ACTION_FOO);
xassert(bindings.arr[1].action == TEST_ACTION_FOO);
/*
* REMOVE foo
*/
xassert(parse_key_binding_section(
"", "foo", "none", ALEN(map), map, &bindings, &conf, "", 0));
xassert(bindings.count == 0);
free(bindings.arr);
}
static bool
parse_section_key_bindings(
const char *key, const char *value, struct config *conf,
@ -2156,6 +2255,15 @@ parse_section_tweak(
LOG_WARN("tweak: grapheme shaping");
}
else if (strcmp(key, "grapheme-width-method") == 0) {
if (strcmp(value, "double-width") == 0)
conf->tweak.grapheme_width_method = GRAPHEME_WIDTH_DOUBLE;
else if (strcmp(value, "wcswidth") == 0)
conf->tweak.grapheme_width_method = GRAPHEME_WIDTH_WCSWIDTH;
LOG_WARN("%s:%d [tweak]: grapheme-width-method=%s", path, lineno, value);
}
else if (strcmp(key, "render-timer") == 0) {
if (strcmp(value, "none") == 0) {
conf->tweak.render_timer_osd = false;
@ -2724,6 +2832,7 @@ config_load(struct config *conf, const char *conf_path,
.fcft_filter = FCFT_SCALING_FILTER_LANCZOS3,
.allow_overflowing_double_width_glyphs = true,
.grapheme_shaping = false,
.grapheme_width_method = GRAPHEME_WIDTH_DOUBLE,
.delayed_render_lower_ns = 500000, /* 0.5ms */
.delayed_render_upper_ns = 16666666 / 2, /* half a frame period (60Hz) */
.max_shm_pool_size = 512 * 1024 * 1024,
@ -2850,6 +2959,15 @@ out:
}
}
#if defined(_DEBUG)
for (size_t i = 0; i < conf->bindings.key.count; i++)
xassert(conf->bindings.key.arr[i].action != BIND_ACTION_NONE);
for (size_t i = 0; i < conf->bindings.search.count; i++)
xassert(conf->bindings.search.arr[i].action != BIND_ACTION_SEARCH_NONE);
for (size_t i = 0; i < conf->bindings.url.count; i++)
xassert(conf->bindings.url.arr[i].action != BIND_ACTION_URL_NONE);
#endif
free(conf_file.path);
if (conf_file.fd >= 0)
close(conf_file.fd);
@ -3032,6 +3150,27 @@ config_clone(const struct config *old)
return conf;
}
UNITTEST
{
struct config original;
user_notifications_t nots = tll_init();
config_override_t overrides = tll_init();
bool ret = config_load(&original, "/dev/null", &nots, &overrides, false);
xassert(ret);
struct config *clone = config_clone(&original);
xassert(clone != NULL);
xassert(clone != &original);
config_free(original);
config_free(*clone);
free(clone);
tll_free(overrides);
tll_free(nots);
}
void
config_free(struct config conf)
{

View file

@ -246,6 +246,7 @@ struct config {
enum fcft_scaling_filter fcft_filter;
bool allow_overflowing_double_width_glyphs;
bool grapheme_shaping;
enum {GRAPHEME_WIDTH_WCSWIDTH, GRAPHEME_WIDTH_DOUBLE} grapheme_width_method;
bool render_timer_osd;
bool render_timer_log;
bool damage_whole_window;

View file

@ -0,0 +1,550 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<svg
width="1000" height="750"
viewBox="0 0 1000 750"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>Gnuplot</title>
<desc>Produced by GNUPLOT 5.4 patchlevel 2 </desc>
<g id="gnuplot_canvas">
<rect x="0" y="0" width="1000" height="750" fill="#ffffff"/>
<defs>
<circle id='gpDot' r='0.5' stroke-width='0.5' stroke='currentColor'/>
<path id='gpPt0' stroke-width='0.222' stroke='currentColor' d='M-1,0 h2 M0,-1 v2'/>
<path id='gpPt1' stroke-width='0.222' stroke='currentColor' d='M-1,-1 L1,1 M1,-1 L-1,1'/>
<path id='gpPt2' stroke-width='0.222' stroke='currentColor' d='M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1'/>
<rect id='gpPt3' stroke-width='0.222' stroke='currentColor' x='-1' y='-1' width='2' height='2'/>
<rect id='gpPt4' stroke-width='0.222' stroke='currentColor' fill='currentColor' x='-1' y='-1' width='2' height='2'/>
<circle id='gpPt5' stroke-width='0.222' stroke='currentColor' cx='0' cy='0' r='1'/>
<use xlink:href='#gpPt5' id='gpPt6' fill='currentColor' stroke='none'/>
<path id='gpPt7' stroke-width='0.222' stroke='currentColor' d='M0,-1.33 L-1.33,0.67 L1.33,0.67 z'/>
<use xlink:href='#gpPt7' id='gpPt8' fill='currentColor' stroke='none'/>
<use xlink:href='#gpPt7' id='gpPt9' stroke='currentColor' transform='rotate(180)'/>
<use xlink:href='#gpPt9' id='gpPt10' fill='currentColor' stroke='none'/>
<use xlink:href='#gpPt3' id='gpPt11' stroke='currentColor' transform='rotate(45)'/>
<use xlink:href='#gpPt11' id='gpPt12' fill='currentColor' stroke='none'/>
<path id='gpPt13' stroke-width='0.222' stroke='currentColor' d='M0,1.330 L1.265,0.411 L0.782,-1.067 L-0.782,-1.076 L-1.265,0.411 z'/>
<use xlink:href='#gpPt13' id='gpPt14' fill='currentColor' stroke='none'/>
<filter id='textbox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
<feFlood flood-color='#FFFFFF' flood-opacity='1' result='bgnd'/>
<feComposite in='SourceGraphic' in2='bgnd' operator='atop'/>
</filter>
<filter id='greybox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
<feFlood flood-color='lightgrey' flood-opacity='1' result='grey'/>
<feComposite in='SourceGraphic' in2='grey' operator='atop'/>
</filter>
</defs>
<g fill="none" color="#FFFFFF" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,559.96 L89.92,559.96 M974.82,559.96 L965.82,559.96 '/> <g transform="translate(72.53,563.86)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 0</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,485.11 L89.92,485.11 M974.82,485.11 L965.82,485.11 '/> <g transform="translate(72.53,489.01)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 200</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,410.26 L89.92,410.26 M974.82,410.26 L965.82,410.26 '/> <g transform="translate(72.53,414.16)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 400</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,335.41 L89.92,335.41 M974.82,335.41 L965.82,335.41 '/> <g transform="translate(72.53,339.31)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 600</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,260.56 L89.92,260.56 M974.82,260.56 L965.82,260.56 '/> <g transform="translate(72.53,264.46)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 800</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,185.71 L89.92,185.71 M974.82,185.71 L965.82,185.71 '/> <g transform="translate(72.53,189.61)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 1000</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,110.86 L89.92,110.86 M974.82,110.86 L965.82,110.86 '/> <g transform="translate(72.53,114.76)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 1200</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,36.01 L89.92,36.01 M974.82,36.01 L965.82,36.01 '/> <g transform="translate(72.53,39.91)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 1400</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M115.76,559.96 M115.76,36.01 '/> <g transform="translate(113.00,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>cursor_motion</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M204.70,559.96 M204.70,36.01 '/> <g transform="translate(201.94,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>dense_cells</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M293.65,559.96 M293.65,36.01 '/> <g transform="translate(290.89,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>light_cells</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M382.59,559.96 M382.59,36.01 '/> <g transform="translate(379.83,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M471.54,559.96 M471.54,36.01 '/> <g transform="translate(468.78,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_bottom_region</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M560.48,559.96 M560.48,36.01 '/> <g transform="translate(557.72,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_bottom_small_region</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M649.43,559.96 M649.43,36.01 '/> <g transform="translate(646.67,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_fullscreen</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M738.37,559.96 M738.37,36.01 '/> <g transform="translate(735.61,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_top_region</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M827.32,559.96 M827.32,36.01 '/> <g transform="translate(824.56,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_top_small_region</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M916.26,559.96 M916.26,36.01 '/> <g transform="translate(913.50,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>unicode</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,36.01 L80.92,559.96 L974.82,559.96 L974.82,36.01 L80.92,36.01 Z '/> <path stroke='rgb(136, 136, 136)' stroke-dasharray='1.0,2.5' d='M175.06,559.95 L175.06,36.00 M264.01,559.95 L264.01,36.00 M352.95,559.95 L352.95,36.00 M441.90,559.95 L441.90,36.00
M530.84,559.95 L530.84,36.00 M619.79,559.95 L619.79,36.00 M708.74,559.95 L708.74,36.00 M797.68,559.95 L797.68,36.00
M886.63,559.95 L886.63,36.00 '/></g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(19.18,297.99) rotate(270)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
<text>milliseconds (lower is better)</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g id="gnuplot_plot_1" ><title>gnuplot_plot_1</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(241.08,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>foot-pgo</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '249.47,22.50 292.03,22.50 292.03,13.50 249.47,13.50 '/>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '94.26,555.47 107.60,555.47 107.60,555.09 94.26,555.09 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M94.26,555.47 L107.60,555.47 L107.60,555.09 L94.26,555.09 L94.26,555.47 Z '/> <path stroke='rgb(148, 0, 211)' d='M94.26,555.09 L107.60,555.09 M100.93,555.84 L100.93,555.47 M100.93,555.09 L100.93,554.72 M91.93,554.72 L109.93,554.72
M91.93,555.84 L109.93,555.84 '/></g>
</g>
<g id="gnuplot_plot_2" ><title>gnuplot_plot_2</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '183.21,545.74 196.55,545.74 196.55,544.99 183.21,544.99 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M183.21,545.74 L196.55,545.74 L196.55,544.99 L183.21,544.99 L183.21,545.74 Z '/> <path stroke='rgb(148, 0, 211)' d='M183.21,545.36 L196.55,545.36 M189.88,546.49 L189.88,545.74 M189.88,544.99 L189.88,543.87 M180.88,543.87 L198.88,543.87
M180.88,546.49 L198.88,546.49 '/></g>
</g>
<g id="gnuplot_plot_3" ><title>gnuplot_plot_3</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '272.15,558.09 285.49,558.09 285.49,557.71 272.15,557.71 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M272.15,558.09 L285.49,558.09 L285.49,557.71 L272.15,557.71 L272.15,558.09 Z '/> <path stroke='rgb(148, 0, 211)' d='M272.15,558.09 L285.49,558.09 M278.82,558.09 M278.82,557.71 M269.82,557.71 L287.82,557.71 M269.82,558.09 L287.82,558.09
'/></g>
</g>
<g id="gnuplot_plot_4" ><title>gnuplot_plot_4</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '361.10,506.82 374.44,506.82 374.44,504.95 361.10,504.95 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M361.10,506.82 L374.44,506.82 L374.44,504.95 L361.10,504.95 L361.10,506.82 Z '/> <path stroke='rgb(148, 0, 211)' d='M361.10,505.69 L374.44,505.69 M367.77,509.44 L367.77,506.82 M367.77,504.95 L367.77,503.45 M358.77,503.45 L376.77,503.45
M358.77,509.44 L376.77,509.44 '/></g>
</g>
<g id="gnuplot_plot_5" ><title>gnuplot_plot_5</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '450.04,512.43 463.38,512.43 463.38,509.06 450.04,509.06 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M450.04,512.43 L463.38,512.43 L463.38,509.06 L450.04,509.06 L450.04,512.43 Z '/> <path stroke='rgb(148, 0, 211)' d='M450.04,510.56 L463.38,510.56 M456.71,514.30 L456.71,512.43 M456.71,509.06 L456.71,507.94 M447.71,507.94 L465.71,507.94
M447.71,514.30 L465.71,514.30 '/></g>
</g>
<g id="gnuplot_plot_6" ><title>gnuplot_plot_6</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '538.99,507.56 552.33,507.56 552.33,505.69 538.99,505.69 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M538.99,507.56 L552.33,507.56 L552.33,505.69 L538.99,505.69 L538.99,507.56 Z '/> <path stroke='rgb(148, 0, 211)' d='M538.99,506.26 L552.33,506.26 M545.66,509.81 L545.66,507.56 M545.66,505.69 L545.66,503.82 M536.66,503.82 L554.66,503.82
M536.66,509.81 L554.66,509.81 '/></g>
</g>
<g id="gnuplot_plot_7" ><title>gnuplot_plot_7</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '627.93,558.09 641.29,558.09 641.29,557.71 627.93,557.71 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M627.93,558.09 L641.29,558.09 L641.29,557.71 L627.93,557.71 L627.93,558.09 Z '/> <path stroke='rgb(148, 0, 211)' d='M627.93,558.09 L641.29,558.09 M634.61,558.46 L634.61,558.09 M634.61,557.71 L634.61,557.34 M625.61,557.34 L643.61,557.34
M625.61,558.46 L643.61,558.46 '/></g>
</g>
<g id="gnuplot_plot_8" ><title>gnuplot_plot_8</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '716.88,512.43 730.22,512.43 730.22,510.93 716.88,510.93 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M716.88,512.43 L730.22,512.43 L730.22,510.93 L716.88,510.93 L716.88,512.43 Z '/> <path stroke='rgb(148, 0, 211)' d='M716.88,511.68 L730.22,511.68 M723.55,514.30 L723.55,512.43 M723.55,510.93 L723.55,509.44 M714.55,509.44 L732.55,509.44
M714.55,514.30 L732.55,514.30 '/></g>
</g>
<g id="gnuplot_plot_9" ><title>gnuplot_plot_9</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '805.82,521.41 819.18,521.41 819.18,507.94 805.82,507.94 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M805.82,521.41 L819.18,521.41 L819.18,507.94 L805.82,507.94 L805.82,521.41 Z '/> <path stroke='rgb(148, 0, 211)' d='M805.82,510.00 L819.18,510.00 M812.50,534.14 L812.50,521.41 M812.50,507.94 L812.50,504.57 M803.50,504.57 L821.50,504.57
M803.50,534.14 L821.50,534.14 '/></g>
</g>
<g id="gnuplot_plot_10" ><title>gnuplot_plot_10</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '894.77,556.22 908.11,556.22 908.11,555.84 894.77,555.84 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M894.77,556.22 L908.11,556.22 L908.11,555.84 L894.77,555.84 L894.77,556.22 Z '/> <path stroke='rgb(148, 0, 211)' d='M894.77,555.84 L908.11,555.84 M901.44,556.22 M901.44,555.84 L901.44,555.47 M892.44,555.47 L910.44,555.47 M892.44,556.22
L910.44,556.22 '/></g>
</g>
<g id="gnuplot_plot_11" ><title>gnuplot_plot_11</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(392.71,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>foot-no-pgo</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '401.10,22.50 443.66,22.50 443.66,13.50 401.10,13.50 '/>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '109.09,554.35 122.43,554.35 122.43,553.97 109.09,553.97 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M109.09,554.35 L122.43,554.35 L122.43,553.97 L109.09,553.97 L109.09,554.35 Z '/> <path stroke='rgb( 0, 158, 115)' d='M109.09,554.35 L122.43,554.35 M115.76,554.72 L115.76,554.35 M115.76,553.97 L115.76,553.60 M106.76,553.60 L124.76,553.60
M106.76,554.72 L124.76,554.72 '/></g>
</g>
<g id="gnuplot_plot_12" ><title>gnuplot_plot_12</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '198.03,542.37 211.37,542.37 211.37,542.00 198.03,542.00 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M198.03,542.37 L211.37,542.37 L211.37,542.00 L198.03,542.00 L198.03,542.37 Z '/> <path stroke='rgb( 0, 158, 115)' d='M198.03,542.37 L211.37,542.37 M204.70,542.74 L204.70,542.37 M204.70,542.00 M195.70,542.00 L213.70,542.00 M195.70,542.74
L213.70,542.74 '/></g>
</g>
<g id="gnuplot_plot_13" ><title>gnuplot_plot_13</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '286.98,557.71 300.32,557.71 300.32,557.34 286.98,557.34 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M286.98,557.71 L300.32,557.71 L300.32,557.34 L286.98,557.34 L286.98,557.71 Z '/> <path stroke='rgb( 0, 158, 115)' d='M286.98,557.71 L300.32,557.71 M293.65,557.71 M293.65,557.34 L293.65,556.97 M284.65,556.97 L302.65,556.97 M284.65,557.71
L302.65,557.71 '/></g>
</g>
<g id="gnuplot_plot_14" ><title>gnuplot_plot_14</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '375.92,509.06 389.26,509.06 389.26,506.63 375.92,506.63 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M375.92,509.06 L389.26,509.06 L389.26,506.63 L375.92,506.63 L375.92,509.06 Z '/> <path stroke='rgb( 0, 158, 115)' d='M375.92,507.56 L389.26,507.56 M382.59,512.43 L382.59,509.06 M382.59,506.63 L382.59,503.45 M373.59,503.45 L391.59,503.45
M373.59,512.43 L391.59,512.43 '/></g>
</g>
<g id="gnuplot_plot_15" ><title>gnuplot_plot_15</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '464.87,514.30 478.21,514.30 478.21,511.87 464.87,511.87 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M464.87,514.30 L478.21,514.30 L478.21,511.87 L464.87,511.87 L464.87,514.30 Z '/> <path stroke='rgb( 0, 158, 115)' d='M464.87,512.80 L478.21,512.80 M471.54,515.80 L471.54,514.30 M471.54,511.87 L471.54,510.18 M462.54,510.18 L480.54,510.18
M462.54,515.80 L480.54,515.80 '/></g>
</g>
<g id="gnuplot_plot_16" ><title>gnuplot_plot_16</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '553.81,513.55 567.15,513.55 567.15,510.56 553.81,510.56 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M553.81,513.55 L567.15,513.55 L567.15,510.56 L553.81,510.56 L553.81,513.55 Z '/> <path stroke='rgb( 0, 158, 115)' d='M553.81,512.06 L567.15,512.06 M560.48,516.92 L560.48,513.55 M560.48,510.56 L560.48,508.69 M551.48,508.69 L569.48,508.69
M551.48,516.92 L569.48,516.92 '/></g>
</g>
<g id="gnuplot_plot_17" ><title>gnuplot_plot_17</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '642.76,558.09 656.10,558.09 656.10,558.09 642.76,558.09 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M642.76,558.09 L656.10,558.09 L642.76,558.09 Z '/> <path stroke='rgb( 0, 158, 115)' d='M642.76,558.09 L656.10,558.09 M649.43,558.09 M640.43,558.09 L658.43,558.09 M640.43,558.09 L658.43,558.09 '/></g>
</g>
<g id="gnuplot_plot_18" ><title>gnuplot_plot_18</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '731.70,516.55 745.04,516.55 745.04,512.80 731.70,512.80 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M731.70,516.55 L745.04,516.55 L745.04,512.80 L731.70,512.80 L731.70,516.55 Z '/> <path stroke='rgb( 0, 158, 115)' d='M731.70,513.93 L745.04,513.93 M738.37,518.79 L738.37,516.55 M738.37,512.80 L738.37,511.68 M729.37,511.68 L747.37,511.68
M729.37,518.79 L747.37,518.79 '/></g>
</g>
<g id="gnuplot_plot_19" ><title>gnuplot_plot_19</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '820.65,519.92 833.99,519.92 833.99,518.42 820.65,518.42 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M820.65,519.92 L833.99,519.92 L833.99,518.42 L820.65,518.42 L820.65,519.92 Z '/> <path stroke='rgb( 0, 158, 115)' d='M820.65,519.17 L833.99,519.17 M827.32,521.04 L827.32,519.92 M827.32,518.42 L827.32,516.55 M818.32,516.55 L836.32,516.55
M818.32,521.04 L836.32,521.04 '/></g>
</g>
<g id="gnuplot_plot_20" ><title>gnuplot_plot_20</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '909.59,556.22 922.95,556.22 922.95,555.84 909.59,555.84 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M909.59,556.22 L922.95,556.22 L922.95,555.84 L909.59,555.84 L909.59,556.22 Z '/> <path stroke='rgb( 0, 158, 115)' d='M909.59,555.84 L922.95,555.84 M916.27,556.22 M916.27,555.84 L916.27,555.47 M907.27,555.47 L925.27,555.47 M907.27,556.22
L925.27,556.22 '/></g>
</g>
<g id="gnuplot_plot_21" ><title>gnuplot_plot_21</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(544.34,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>alacritty</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '552.73,22.50 595.29,22.50 595.29,13.50 552.73,13.50 '/>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '123.91,550.23 137.25,550.23 137.25,549.86 123.91,549.86 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M123.91,550.23 L137.25,550.23 L137.25,549.86 L123.91,549.86 L123.91,550.23 Z '/> <path stroke='rgb( 86, 180, 233)' d='M123.91,549.86 L137.25,549.86 M130.58,550.60 L130.58,550.23 M130.58,549.86 L130.58,549.48 M121.58,549.48 L139.58,549.48
M121.58,550.60 L139.58,550.60 '/></g>
</g>
<g id="gnuplot_plot_22" ><title>gnuplot_plot_22</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '212.86,527.77 226.20,527.77 226.20,527.03 212.86,527.03 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M212.86,527.77 L226.20,527.77 L226.20,527.03 L212.86,527.03 L212.86,527.77 Z '/> <path stroke='rgb( 86, 180, 233)' d='M212.86,527.40 L226.20,527.40 M219.53,528.90 L219.53,527.77 M219.53,527.03 L219.53,526.28 M210.53,526.28 L228.53,526.28
M210.53,528.90 L228.53,528.90 '/></g>
</g>
<g id="gnuplot_plot_23" ><title>gnuplot_plot_23</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '301.80,555.09 315.14,555.09 315.14,555.09 301.80,555.09 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M301.80,555.09 L315.14,555.09 L301.80,555.09 Z '/> <path stroke='rgb( 86, 180, 233)' d='M301.80,555.09 L315.14,555.09 M308.47,555.09 M299.47,555.09 L317.47,555.09 M299.47,555.09 L317.47,555.09 '/></g>
</g>
<g id="gnuplot_plot_24" ><title>gnuplot_plot_24</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '390.75,511.31 404.09,511.31 404.09,508.31 390.75,508.31 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M390.75,511.31 L404.09,511.31 L404.09,508.31 L390.75,508.31 L390.75,511.31 Z '/> <path stroke='rgb( 86, 180, 233)' d='M390.75,509.44 L404.09,509.44 M397.42,515.42 L397.42,511.31 M397.42,508.31 L397.42,505.32 M388.42,505.32 L406.42,505.32
M388.42,515.42 L406.42,515.42 '/></g>
</g>
<g id="gnuplot_plot_25" ><title>gnuplot_plot_25</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '479.69,516.92 493.03,516.92 493.03,515.80 479.69,515.80 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M479.69,516.92 L493.03,516.92 L493.03,515.80 L479.69,515.80 L479.69,516.92 Z '/> <path stroke='rgb( 86, 180, 233)' d='M479.69,516.17 L493.03,516.17 M486.36,518.42 L486.36,516.92 M486.36,515.80 L486.36,514.68 M477.36,514.68 L495.36,514.68
M477.36,518.42 L495.36,518.42 '/></g>
</g>
<g id="gnuplot_plot_26" ><title>gnuplot_plot_26</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '568.64,513.55 581.98,513.55 581.98,511.31 568.64,511.31 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M568.64,513.55 L581.98,513.55 L581.98,511.31 L568.64,511.31 L568.64,513.55 Z '/> <path stroke='rgb( 86, 180, 233)' d='M568.64,512.43 L581.98,512.43 M575.31,516.55 L575.31,513.55 M575.31,511.31 L575.31,508.69 M566.31,508.69 L584.31,508.69
M566.31,516.55 L584.31,516.55 '/></g>
</g>
<g id="gnuplot_plot_27" ><title>gnuplot_plot_27</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '657.58,555.47 670.92,555.47 670.92,555.47 657.58,555.47 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M657.58,555.47 L670.92,555.47 L657.58,555.47 Z '/> <path stroke='rgb( 86, 180, 233)' d='M657.58,555.47 L670.92,555.47 M664.25,555.47 M655.25,555.47 L673.25,555.47 M655.25,555.47 L673.25,555.47 '/></g>
</g>
<g id="gnuplot_plot_28" ><title>gnuplot_plot_28</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '746.53,515.80 759.87,515.80 759.87,513.18 746.53,513.18 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M746.53,515.80 L759.87,515.80 L759.87,513.18 L746.53,513.18 L746.53,515.80 Z '/> <path stroke='rgb( 86, 180, 233)' d='M746.53,514.30 L759.87,514.30 M753.20,519.54 L753.20,515.80 M753.20,513.18 L753.20,511.31 M744.20,511.31 L762.20,511.31
M744.20,519.54 L762.20,519.54 '/></g>
</g>
<g id="gnuplot_plot_29" ><title>gnuplot_plot_29</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '835.47,509.81 848.81,509.81 848.81,507.19 835.47,507.19 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M835.47,509.81 L848.81,509.81 L848.81,507.19 L835.47,507.19 L835.47,509.81 Z '/> <path stroke='rgb( 86, 180, 233)' d='M835.47,508.69 L848.81,508.69 M842.14,512.06 L842.14,509.81 M842.14,507.19 L842.14,503.82 M833.14,503.82 L851.14,503.82
M833.14,512.06 L851.14,512.06 '/></g>
</g>
<g id="gnuplot_plot_30" ><title>gnuplot_plot_30</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '924.42,554.72 937.76,554.72 937.76,554.72 924.42,554.72 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M924.42,554.72 L937.76,554.72 L924.42,554.72 Z '/> <path stroke='rgb( 86, 180, 233)' d='M924.42,554.72 L937.76,554.72 M931.09,554.72 M922.09,554.72 L940.09,554.72 M922.09,554.72 L940.09,554.72 '/></g>
</g>
<g id="gnuplot_plot_31" ><title>gnuplot_plot_31</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(695.97,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>urxvt</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '704.36,22.50 746.92,22.50 746.92,13.50 704.36,13.50 '/>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '138.73,551.35 152.09,551.35 152.09,550.98 138.73,550.98 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M138.73,551.35 L152.09,551.35 L152.09,550.98 L138.73,550.98 L138.73,551.35 Z '/> <path stroke='rgb(230, 159, 0)' d='M138.73,551.35 L152.09,551.35 M145.41,551.35 M145.41,550.98 M136.41,550.98 L154.41,550.98 M136.41,551.35 L154.41,551.35
'/></g>
</g>
<g id="gnuplot_plot_32" ><title>gnuplot_plot_32</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_33" ><title>gnuplot_plot_33</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '316.62,553.97 329.98,553.97 329.98,553.97 316.62,553.97 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M316.62,553.97 L329.98,553.97 L316.62,553.97 Z '/> <path stroke='rgb(230, 159, 0)' d='M316.62,553.97 L329.98,553.97 M323.30,553.97 M314.30,553.97 L332.30,553.97 M314.30,553.97 L332.30,553.97 '/></g>
</g>
<g id="gnuplot_plot_34" ><title>gnuplot_plot_34</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '405.57,516.92 418.91,516.92 418.91,515.05 405.57,515.05 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M405.57,516.92 L418.91,516.92 L418.91,515.05 L405.57,515.05 L405.57,516.92 Z '/> <path stroke='rgb(230, 159, 0)' d='M405.57,516.17 L418.91,516.17 M412.24,518.42 L412.24,516.92 M412.24,515.05 L412.24,513.55 M403.24,513.55 L421.24,513.55
M403.24,518.42 L421.24,518.42 '/></g>
</g>
<g id="gnuplot_plot_35" ><title>gnuplot_plot_35</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '494.52,517.30 507.86,517.30 507.86,514.30 494.52,514.30 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M494.52,517.30 L507.86,517.30 L507.86,514.30 L494.52,514.30 L494.52,517.30 Z '/> <path stroke='rgb(230, 159, 0)' d='M494.52,516.17 L507.86,516.17 M501.19,519.92 L501.19,517.30 M501.19,514.30 L501.19,513.18 M492.19,513.18 L510.19,513.18
M492.19,519.92 L510.19,519.92 '/></g>
</g>
<g id="gnuplot_plot_36" ><title>gnuplot_plot_36</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '583.46,512.06 596.80,512.06 596.80,507.56 583.46,507.56 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M583.46,512.06 L596.80,512.06 L596.80,507.56 L583.46,507.56 L583.46,512.06 Z '/> <path stroke='rgb(230, 159, 0)' d='M583.46,510.18 L596.80,510.18 M590.13,515.05 L590.13,512.06 M590.13,507.56 L590.13,500.83 M581.13,500.83 L599.13,500.83
M581.13,515.05 L599.13,515.05 '/></g>
</g>
<g id="gnuplot_plot_37" ><title>gnuplot_plot_37</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '672.41,555.47 685.75,555.47 685.75,555.47 672.41,555.47 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M672.41,555.47 L685.75,555.47 L672.41,555.47 Z '/> <path stroke='rgb(230, 159, 0)' d='M672.41,555.47 L685.75,555.47 M679.08,555.47 M670.08,555.47 L688.08,555.47 M670.08,555.47 L688.08,555.47 '/></g>
</g>
<g id="gnuplot_plot_38" ><title>gnuplot_plot_38</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '761.35,432.34 774.69,432.34 774.69,431.59 761.35,431.59 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M761.35,432.34 L774.69,432.34 L774.69,431.59 L761.35,431.59 L761.35,432.34 Z '/> <path stroke='rgb(230, 159, 0)' d='M761.35,432.15 L774.69,432.15 M768.02,433.09 L768.02,432.34 M768.02,431.59 L768.02,430.47 M759.02,430.47 L777.02,430.47
M759.02,433.09 L777.02,433.09 '/></g>
</g>
<g id="gnuplot_plot_39" ><title>gnuplot_plot_39</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '850.30,480.24 863.64,480.24 863.64,471.26 850.30,471.26 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M850.30,480.24 L863.64,480.24 L863.64,471.26 L850.30,471.26 L850.30,480.24 Z '/> <path stroke='rgb(230, 159, 0)' d='M850.30,479.87 L863.64,479.87 M856.97,480.62 L856.97,480.24 M856.97,471.26 L856.97,470.51 M847.97,470.51 L865.97,470.51
M847.97,480.62 L865.97,480.62 '/></g>
</g>
<g id="gnuplot_plot_40" ><title>gnuplot_plot_40</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '939.24,409.14 952.58,409.14 952.58,183.46 939.24,183.46 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M939.24,409.14 L952.58,409.14 L952.58,183.46 L939.24,183.46 L939.24,409.14 Z '/> <path stroke='rgb(230, 159, 0)' d='M939.24,315.20 L952.58,315.20 M945.91,475.75 L945.91,409.14 M945.91,183.46 L945.91,128.45 M936.91,128.45 L954.91,128.45
M936.91,475.75 L954.91,475.75 '/></g>
</g>
<g id="gnuplot_plot_41" ><title>gnuplot_plot_41</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(847.60,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>xterm</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(240, 228, 66)' fill-opacity = '0.250000' points = '855.99,22.50 898.55,22.50 898.55,13.50 855.99,13.50 '/>
<polygon fill = 'rgb(240, 228, 66)' fill-opacity = '0.250000' points = '153.56,72.31 166.90,72.31 166.90,71.00 153.56,71.00 '/>
</g>
<path stroke='rgb(240, 228, 66)' d='M153.56,72.31 L166.90,72.31 L166.90,71.00 L153.56,71.00 L153.56,72.31 Z '/> <path stroke='rgb(240, 228, 66)' d='M153.56,71.38 L166.90,71.38 M160.23,73.43 L160.23,72.31 M160.23,71.00 L160.23,70.82 M151.23,70.82 L169.23,70.82
M151.23,73.43 L169.23,73.43 '/></g>
</g>
<g id="gnuplot_plot_42" ><title>gnuplot_plot_42</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_43" ><title>gnuplot_plot_43</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(240, 228, 66)' fill-opacity = '0.250000' points = '331.45,537.50 344.79,537.50 344.79,537.50 331.45,537.50 '/>
</g>
<path stroke='rgb(240, 228, 66)' d='M331.45,537.50 L344.79,537.50 L331.45,537.50 Z '/> <path stroke='rgb(240, 228, 66)' d='M331.45,537.50 L344.79,537.50 M338.12,537.50 M329.12,537.50 L347.12,537.50 M329.12,537.50 L347.12,537.50 '/></g>
</g>
<g id="gnuplot_plot_44" ><title>gnuplot_plot_44</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_45" ><title>gnuplot_plot_45</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_46" ><title>gnuplot_plot_46</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_47" ><title>gnuplot_plot_47</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(240, 228, 66)' fill-opacity = '0.250000' points = '687.23,515.80 700.57,515.80 700.57,515.05 687.23,515.05 '/>
</g>
<path stroke='rgb(240, 228, 66)' d='M687.23,515.80 L700.57,515.80 L700.57,515.05 L687.23,515.05 L687.23,515.80 Z '/> <path stroke='rgb(240, 228, 66)' d='M687.23,515.42 L700.57,515.42 M693.90,516.55 L693.90,515.80 M693.90,515.05 L693.90,514.30 M684.90,514.30 L702.90,514.30
M684.90,516.55 L702.90,516.55 '/></g>
</g>
<g id="gnuplot_plot_48" ><title>gnuplot_plot_48</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_49" ><title>gnuplot_plot_49</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_50" ><title>gnuplot_plot_50</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g fill="none" color="#FFFFFF" stroke="rgb(240, 228, 66)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="black" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,36.01 L80.92,559.96 L974.82,559.96 L974.82,36.01 L80.92,36.01 Z '/></g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -0,0 +1,572 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<svg
width="1000" height="750"
viewBox="0 0 1000 750"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>Gnuplot</title>
<desc>Produced by GNUPLOT 5.4 patchlevel 2 </desc>
<g id="gnuplot_canvas">
<rect x="0" y="0" width="1000" height="750" fill="#ffffff"/>
<defs>
<circle id='gpDot' r='0.5' stroke-width='0.5' stroke='currentColor'/>
<path id='gpPt0' stroke-width='0.222' stroke='currentColor' d='M-1,0 h2 M0,-1 v2'/>
<path id='gpPt1' stroke-width='0.222' stroke='currentColor' d='M-1,-1 L1,1 M1,-1 L-1,1'/>
<path id='gpPt2' stroke-width='0.222' stroke='currentColor' d='M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1'/>
<rect id='gpPt3' stroke-width='0.222' stroke='currentColor' x='-1' y='-1' width='2' height='2'/>
<rect id='gpPt4' stroke-width='0.222' stroke='currentColor' fill='currentColor' x='-1' y='-1' width='2' height='2'/>
<circle id='gpPt5' stroke-width='0.222' stroke='currentColor' cx='0' cy='0' r='1'/>
<use xlink:href='#gpPt5' id='gpPt6' fill='currentColor' stroke='none'/>
<path id='gpPt7' stroke-width='0.222' stroke='currentColor' d='M0,-1.33 L-1.33,0.67 L1.33,0.67 z'/>
<use xlink:href='#gpPt7' id='gpPt8' fill='currentColor' stroke='none'/>
<use xlink:href='#gpPt7' id='gpPt9' stroke='currentColor' transform='rotate(180)'/>
<use xlink:href='#gpPt9' id='gpPt10' fill='currentColor' stroke='none'/>
<use xlink:href='#gpPt3' id='gpPt11' stroke='currentColor' transform='rotate(45)'/>
<use xlink:href='#gpPt11' id='gpPt12' fill='currentColor' stroke='none'/>
<path id='gpPt13' stroke-width='0.222' stroke='currentColor' d='M0,1.330 L1.265,0.411 L0.782,-1.067 L-0.782,-1.076 L-1.265,0.411 z'/>
<use xlink:href='#gpPt13' id='gpPt14' fill='currentColor' stroke='none'/>
<filter id='textbox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
<feFlood flood-color='#FFFFFF' flood-opacity='1' result='bgnd'/>
<feComposite in='SourceGraphic' in2='bgnd' operator='atop'/>
</filter>
<filter id='greybox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
<feFlood flood-color='lightgrey' flood-opacity='1' result='grey'/>
<feComposite in='SourceGraphic' in2='grey' operator='atop'/>
</filter>
</defs>
<g fill="none" color="#FFFFFF" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,559.96 L89.92,559.96 M974.82,559.96 L965.82,559.96 '/> <g transform="translate(72.53,563.86)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 0</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,507.56 L89.92,507.56 M974.82,507.56 L965.82,507.56 '/> <g transform="translate(72.53,511.46)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 200</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,455.17 L89.92,455.17 M974.82,455.17 L965.82,455.17 '/> <g transform="translate(72.53,459.07)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 400</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,402.77 L89.92,402.77 M974.82,402.77 L965.82,402.77 '/> <g transform="translate(72.53,406.67)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 600</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,350.38 L89.92,350.38 M974.82,350.38 L965.82,350.38 '/> <g transform="translate(72.53,354.28)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 800</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,297.98 L89.92,297.98 M974.82,297.98 L965.82,297.98 '/> <g transform="translate(72.53,301.88)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 1000</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,245.59 L89.92,245.59 M974.82,245.59 L965.82,245.59 '/> <g transform="translate(72.53,249.49)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 1200</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,193.19 L89.92,193.19 M974.82,193.19 L965.82,193.19 '/> <g transform="translate(72.53,197.09)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 1400</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,140.80 L89.92,140.80 M974.82,140.80 L965.82,140.80 '/> <g transform="translate(72.53,144.70)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 1600</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,88.40 L89.92,88.40 M974.82,88.40 L965.82,88.40 '/> <g transform="translate(72.53,92.30)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 1800</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,36.01 L89.92,36.01 M974.82,36.01 L965.82,36.01 '/> <g transform="translate(72.53,39.91)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text> 2000</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M115.76,559.96 M115.76,36.01 '/> <g transform="translate(113.00,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>cursor_motion</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M204.70,559.96 M204.70,36.01 '/> <g transform="translate(201.94,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>dense_cells</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M293.65,559.96 M293.65,36.01 '/> <g transform="translate(290.89,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>light_cells</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M382.59,559.96 M382.59,36.01 '/> <g transform="translate(379.83,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M471.54,559.96 M471.54,36.01 '/> <g transform="translate(468.78,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_bottom_region</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M560.48,559.96 M560.48,36.01 '/> <g transform="translate(557.72,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_bottom_small_region</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M649.43,559.96 M649.43,36.01 '/> <g transform="translate(646.67,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_fullscreen</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M738.37,559.96 M738.37,36.01 '/> <g transform="translate(735.61,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_top_region</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M827.32,559.96 M827.32,36.01 '/> <g transform="translate(824.56,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>scrolling_top_small_region</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M916.26,559.96 M916.26,36.01 '/> <g transform="translate(913.50,571.11) rotate(-315)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start">
<text>unicode</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,36.01 L80.92,559.96 L974.82,559.96 L974.82,36.01 L80.92,36.01 Z '/> <path stroke='rgb(136, 136, 136)' stroke-dasharray='1.0,2.5' d='M175.06,559.95 L175.06,36.00 M264.01,559.95 L264.01,36.00 M352.95,559.95 L352.95,36.00 M441.90,559.95 L441.90,36.00
M530.84,559.95 L530.84,36.00 M619.79,559.95 L619.79,36.00 M708.74,559.95 L708.74,36.00 M797.68,559.95 L797.68,36.00
M886.63,559.95 L886.63,36.00 '/></g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(19.18,297.99) rotate(270)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
<text>milliseconds (lower is better)</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g id="gnuplot_plot_1" ><title>gnuplot_plot_1</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(241.08,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>foot-pgo</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '249.47,22.50 292.03,22.50 292.03,13.50 249.47,13.50 '/>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '94.26,556.55 107.60,556.55 107.60,556.03 94.26,556.03 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M94.26,556.55 L107.60,556.55 L107.60,556.03 L94.26,556.03 L94.26,556.55 Z '/> <path stroke='rgb(148, 0, 211)' d='M94.26,556.29 L107.60,556.29 M100.93,556.82 L100.93,556.55 M100.93,556.03 L100.93,555.24 M91.93,555.24 L109.93,555.24
M91.93,556.82 L109.93,556.82 '/></g>
</g>
<g id="gnuplot_plot_2" ><title>gnuplot_plot_2</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '183.21,550.27 196.55,550.27 196.55,548.43 183.21,548.43 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M183.21,550.27 L196.55,550.27 L196.55,548.43 L183.21,548.43 L183.21,550.27 Z '/> <path stroke='rgb(148, 0, 211)' d='M183.21,549.74 L196.55,549.74 M189.88,550.79 L189.88,550.27 M189.88,548.43 L189.88,547.12 M180.88,547.12 L198.88,547.12
M180.88,550.79 L198.88,550.79 '/></g>
</g>
<g id="gnuplot_plot_3" ><title>gnuplot_plot_3</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '272.15,558.13 285.49,558.13 285.49,557.86 272.15,557.86 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M272.15,558.13 L285.49,558.13 L285.49,557.86 L272.15,557.86 L272.15,558.13 Z '/> <path stroke='rgb(148, 0, 211)' d='M272.15,557.86 L285.49,557.86 M278.82,558.39 L278.82,558.13 M278.82,557.86 L278.82,557.60 M269.82,557.60 L287.82,557.60
M269.82,558.39 L287.82,558.39 '/></g>
</g>
<g id="gnuplot_plot_4" ><title>gnuplot_plot_4</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '361.10,521.45 374.44,521.45 374.44,516.47 361.10,516.47 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M361.10,521.45 L374.44,521.45 L374.44,516.47 L361.10,516.47 L361.10,521.45 Z '/> <path stroke='rgb(148, 0, 211)' d='M361.10,518.83 L374.44,518.83 M367.77,524.33 L367.77,521.45 M367.77,516.47 L367.77,510.71 M358.77,510.71 L376.77,510.71
M358.77,524.33 L376.77,524.33 '/></g>
</g>
<g id="gnuplot_plot_5" ><title>gnuplot_plot_5</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '450.04,523.02 463.38,523.02 463.38,516.47 450.04,516.47 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M450.04,523.02 L463.38,523.02 L463.38,516.47 L450.04,516.47 L450.04,523.02 Z '/> <path stroke='rgb(148, 0, 211)' d='M450.04,519.62 L463.38,519.62 M456.71,526.43 L456.71,523.02 M456.71,516.47 L456.71,508.61 M447.71,508.61 L465.71,508.61
M447.71,526.43 L465.71,526.43 '/></g>
</g>
<g id="gnuplot_plot_6" ><title>gnuplot_plot_6</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '538.99,527.21 552.33,527.21 552.33,519.88 538.99,519.88 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M538.99,527.21 L552.33,527.21 L552.33,519.88 L538.99,519.88 L538.99,527.21 Z '/> <path stroke='rgb(148, 0, 211)' d='M538.99,521.19 L552.33,521.19 M545.66,528.52 L545.66,527.21 M545.66,519.88 L545.66,514.64 M536.66,514.64 L554.66,514.64
M536.66,528.52 L554.66,528.52 '/></g>
</g>
<g id="gnuplot_plot_7" ><title>gnuplot_plot_7</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '627.93,557.08 641.29,557.08 641.29,556.82 627.93,556.82 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M627.93,557.08 L641.29,557.08 L641.29,556.82 L627.93,556.82 L627.93,557.08 Z '/> <path stroke='rgb(148, 0, 211)' d='M627.93,557.08 L641.29,557.08 M634.61,557.34 L634.61,557.08 M634.61,556.82 L634.61,556.55 M625.61,556.55 L643.61,556.55
M625.61,557.34 L643.61,557.34 '/></g>
</g>
<g id="gnuplot_plot_8" ><title>gnuplot_plot_8</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '716.88,524.33 730.22,524.33 730.22,517.78 716.88,517.78 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M716.88,524.33 L730.22,524.33 L730.22,517.78 L716.88,517.78 L716.88,524.33 Z '/> <path stroke='rgb(148, 0, 211)' d='M716.88,521.45 L730.22,521.45 M723.55,526.17 L723.55,524.33 M723.55,517.78 L723.55,511.23 M714.55,511.23 L732.55,511.23
M714.55,526.17 L732.55,526.17 '/></g>
</g>
<g id="gnuplot_plot_9" ><title>gnuplot_plot_9</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '805.82,525.38 819.18,525.38 819.18,519.88 805.82,519.88 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M805.82,525.38 L819.18,525.38 L819.18,519.88 L805.82,519.88 L805.82,525.38 Z '/> <path stroke='rgb(148, 0, 211)' d='M805.82,521.32 L819.18,521.32 M812.50,528.26 L812.50,525.38 M812.50,519.88 L812.50,513.59 M803.50,513.59 L821.50,513.59
M803.50,528.26 L821.50,528.26 '/></g>
</g>
<g id="gnuplot_plot_10" ><title>gnuplot_plot_10</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(148, 0, 211)' fill-opacity = '0.250000' points = '894.77,555.24 908.11,555.24 908.11,554.46 894.77,554.46 '/>
</g>
<path stroke='rgb(148, 0, 211)' d='M894.77,555.24 L908.11,555.24 L908.11,554.46 L894.77,554.46 L894.77,555.24 Z '/> <path stroke='rgb(148, 0, 211)' d='M894.77,554.98 L908.11,554.98 M901.44,555.77 L901.44,555.24 M901.44,554.46 L901.44,553.41 M892.44,553.41 L910.44,553.41
M892.44,555.77 L910.44,555.77 '/></g>
</g>
<g id="gnuplot_plot_11" ><title>gnuplot_plot_11</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(392.71,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>foot-no-pgo</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '401.10,22.50 443.66,22.50 443.66,13.50 401.10,13.50 '/>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '109.09,556.03 122.43,556.03 122.43,555.51 109.09,555.51 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M109.09,556.03 L122.43,556.03 L122.43,555.51 L109.09,555.51 L109.09,556.03 Z '/> <path stroke='rgb( 0, 158, 115)' d='M109.09,555.77 L122.43,555.77 M115.76,556.29 L115.76,556.03 M115.76,555.51 L115.76,554.98 M106.76,554.98 L124.76,554.98
M106.76,556.29 L124.76,556.29 '/></g>
</g>
<g id="gnuplot_plot_12" ><title>gnuplot_plot_12</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '198.03,547.12 211.37,547.12 211.37,545.81 198.03,545.81 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M198.03,547.12 L211.37,547.12 L211.37,545.81 L198.03,545.81 L198.03,547.12 Z '/> <path stroke='rgb( 0, 158, 115)' d='M198.03,546.60 L211.37,546.60 M204.70,547.91 L204.70,547.12 M204.70,545.81 L204.70,543.98 M195.70,543.98 L213.70,543.98
M195.70,547.91 L213.70,547.91 '/></g>
</g>
<g id="gnuplot_plot_13" ><title>gnuplot_plot_13</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '286.98,557.86 300.32,557.86 300.32,557.60 286.98,557.60 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M286.98,557.86 L300.32,557.86 L300.32,557.60 L286.98,557.60 L286.98,557.86 Z '/> <path stroke='rgb( 0, 158, 115)' d='M286.98,557.86 L300.32,557.86 M293.65,558.13 L293.65,557.86 M293.65,557.60 L293.65,557.34 M284.65,557.34 L302.65,557.34
M284.65,558.13 L302.65,558.13 '/></g>
</g>
<g id="gnuplot_plot_14" ><title>gnuplot_plot_14</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '375.92,521.19 389.26,521.19 389.26,515.95 375.92,515.95 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M375.92,521.19 L389.26,521.19 L389.26,515.95 L375.92,515.95 L375.92,521.19 Z '/> <path stroke='rgb( 0, 158, 115)' d='M375.92,518.57 L389.26,518.57 M382.59,525.12 L382.59,521.19 M382.59,515.95 L382.59,511.23 M373.59,511.23 L391.59,511.23
M373.59,525.12 L391.59,525.12 '/></g>
</g>
<g id="gnuplot_plot_15" ><title>gnuplot_plot_15</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '464.87,523.55 478.21,523.55 478.21,518.04 464.87,518.04 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M464.87,523.55 L478.21,523.55 L478.21,518.04 L464.87,518.04 L464.87,523.55 Z '/> <path stroke='rgb( 0, 158, 115)' d='M464.87,520.93 L478.21,520.93 M471.54,525.90 L471.54,523.55 M471.54,518.04 L471.54,512.02 M462.54,512.02 L480.54,512.02
M462.54,525.90 L480.54,525.90 '/></g>
</g>
<g id="gnuplot_plot_16" ><title>gnuplot_plot_16</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '553.81,526.69 567.15,526.69 567.15,519.88 553.81,519.88 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M553.81,526.69 L567.15,526.69 L567.15,519.88 L553.81,519.88 L553.81,526.69 Z '/> <path stroke='rgb( 0, 158, 115)' d='M553.81,524.07 L567.15,524.07 M560.48,528.26 L560.48,526.69 M560.48,519.88 L560.48,512.28 M551.48,512.28 L569.48,512.28
M551.48,528.26 L569.48,528.26 '/></g>
</g>
<g id="gnuplot_plot_17" ><title>gnuplot_plot_17</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '642.76,557.08 656.10,557.08 656.10,556.55 642.76,556.55 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M642.76,557.08 L656.10,557.08 L656.10,556.55 L642.76,556.55 L642.76,557.08 Z '/> <path stroke='rgb( 0, 158, 115)' d='M642.76,556.82 L656.10,556.82 M649.43,557.86 L649.43,557.08 M649.43,556.55 L649.43,555.77 M640.43,555.77 L658.43,555.77
M640.43,557.86 L658.43,557.86 '/></g>
</g>
<g id="gnuplot_plot_18" ><title>gnuplot_plot_18</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '731.70,524.72 745.04,524.72 745.04,518.57 731.70,518.57 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M731.70,524.72 L745.04,524.72 L745.04,518.57 L731.70,518.57 L731.70,524.72 Z '/> <path stroke='rgb( 0, 158, 115)' d='M731.70,522.24 L745.04,522.24 M738.37,526.69 L738.37,524.72 M738.37,518.57 L738.37,509.92 M729.37,509.92 L747.37,509.92
M729.37,526.69 L747.37,526.69 '/></g>
</g>
<g id="gnuplot_plot_19" ><title>gnuplot_plot_19</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '820.65,522.50 833.99,522.50 833.99,518.83 820.65,518.83 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M820.65,522.50 L833.99,522.50 L833.99,518.83 L820.65,518.83 L820.65,522.50 Z '/> <path stroke='rgb( 0, 158, 115)' d='M820.65,520.40 L833.99,520.40 M827.32,526.95 L827.32,522.50 M827.32,518.83 L827.32,514.90 M818.32,514.90 L836.32,514.90
M818.32,526.95 L836.32,526.95 '/></g>
</g>
<g id="gnuplot_plot_20" ><title>gnuplot_plot_20</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 0, 158, 115)' fill-opacity = '0.250000' points = '909.59,554.98 922.95,554.98 922.95,554.20 909.59,554.20 '/>
</g>
<path stroke='rgb( 0, 158, 115)' d='M909.59,554.98 L922.95,554.98 L922.95,554.20 L909.59,554.20 L909.59,554.98 Z '/> <path stroke='rgb( 0, 158, 115)' d='M909.59,554.72 L922.95,554.72 M916.27,555.51 L916.27,554.98 M916.27,554.20 L916.27,553.15 M907.27,553.15 L925.27,553.15
M907.27,555.51 L925.27,555.51 '/></g>
</g>
<g id="gnuplot_plot_21" ><title>gnuplot_plot_21</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(544.34,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>alacritty</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '552.73,22.50 595.29,22.50 595.29,13.50 552.73,13.50 '/>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '123.91,553.41 137.25,553.41 137.25,552.62 123.91,552.62 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M123.91,553.41 L137.25,553.41 L137.25,552.62 L123.91,552.62 L123.91,553.41 Z '/> <path stroke='rgb( 86, 180, 233)' d='M123.91,553.02 L137.25,553.02 M130.58,554.20 L130.58,553.41 M130.58,552.62 L130.58,551.58 M121.58,551.58 L139.58,551.58
M121.58,554.20 L139.58,554.20 '/></g>
</g>
<g id="gnuplot_plot_22" ><title>gnuplot_plot_22</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '212.86,539.00 226.20,539.00 226.20,531.93 212.86,531.93 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M212.86,539.00 L226.20,539.00 L226.20,531.93 L212.86,531.93 L212.86,539.00 Z '/> <path stroke='rgb( 86, 180, 233)' d='M212.86,536.91 L226.20,536.91 M219.53,540.31 L219.53,539.00 M219.53,531.93 L219.53,530.09 M210.53,530.09 L228.53,530.09
M210.53,540.31 L228.53,540.31 '/></g>
</g>
<g id="gnuplot_plot_23" ><title>gnuplot_plot_23</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '301.80,554.46 315.14,554.46 315.14,554.20 301.80,554.20 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M301.80,554.46 L315.14,554.46 L315.14,554.20 L301.80,554.20 L301.80,554.46 Z '/> <path stroke='rgb( 86, 180, 233)' d='M301.80,554.46 L315.14,554.46 M308.47,554.72 L308.47,554.46 M308.47,554.20 L308.47,553.93 M299.47,553.93 L317.47,553.93
M299.47,554.72 L317.47,554.72 '/></g>
</g>
<g id="gnuplot_plot_24" ><title>gnuplot_plot_24</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '390.75,524.59 404.09,524.59 404.09,517.78 390.75,517.78 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M390.75,524.59 L404.09,524.59 L404.09,517.78 L390.75,517.78 L390.75,524.59 Z '/> <path stroke='rgb( 86, 180, 233)' d='M390.75,520.66 L404.09,520.66 M397.42,527.74 L397.42,524.59 M397.42,517.78 L397.42,515.16 M388.42,515.16 L406.42,515.16
M388.42,527.74 L406.42,527.74 '/></g>
</g>
<g id="gnuplot_plot_25" ><title>gnuplot_plot_25</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '479.69,524.33 493.03,524.33 493.03,522.24 479.69,522.24 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M479.69,524.33 L493.03,524.33 L493.03,522.24 L479.69,522.24 L479.69,524.33 Z '/> <path stroke='rgb( 86, 180, 233)' d='M479.69,523.02 L493.03,523.02 M486.36,526.43 L486.36,524.33 M486.36,522.24 L486.36,519.09 M477.36,519.09 L495.36,519.09
M477.36,526.43 L495.36,526.43 '/></g>
</g>
<g id="gnuplot_plot_26" ><title>gnuplot_plot_26</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '568.64,517.78 581.98,517.78 581.98,515.42 568.64,515.42 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M568.64,517.78 L581.98,517.78 L581.98,515.42 L568.64,515.42 L568.64,517.78 Z '/> <path stroke='rgb( 86, 180, 233)' d='M568.64,516.21 L581.98,516.21 M575.31,521.19 L575.31,517.78 M575.31,515.42 L575.31,513.85 M566.31,513.85 L584.31,513.85
M566.31,521.19 L584.31,521.19 '/></g>
</g>
<g id="gnuplot_plot_27" ><title>gnuplot_plot_27</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '657.58,554.20 670.92,554.20 670.92,553.67 657.58,553.67 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M657.58,554.20 L670.92,554.20 L670.92,553.67 L657.58,553.67 L657.58,554.20 Z '/> <path stroke='rgb( 86, 180, 233)' d='M657.58,553.93 L670.92,553.93 M664.25,554.72 L664.25,554.20 M664.25,553.67 L664.25,552.89 M655.25,552.89 L673.25,552.89
M655.25,554.72 L673.25,554.72 '/></g>
</g>
<g id="gnuplot_plot_28" ><title>gnuplot_plot_28</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '746.53,521.45 759.87,521.45 759.87,516.47 746.53,516.47 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M746.53,521.45 L759.87,521.45 L759.87,516.47 L746.53,516.47 L746.53,521.45 Z '/> <path stroke='rgb( 86, 180, 233)' d='M746.53,518.31 L759.87,518.31 M753.20,528.52 L753.20,521.45 M753.20,516.47 L753.20,514.64 M744.20,514.64 L762.20,514.64
M744.20,528.52 L762.20,528.52 '/></g>
</g>
<g id="gnuplot_plot_29" ><title>gnuplot_plot_29</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '835.47,520.40 848.81,520.40 848.81,515.69 835.47,515.69 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M835.47,520.40 L848.81,520.40 L848.81,515.69 L835.47,515.69 L835.47,520.40 Z '/> <path stroke='rgb( 86, 180, 233)' d='M835.47,516.21 L848.81,516.21 M842.14,526.95 L842.14,520.40 M842.14,515.69 L842.14,508.61 M833.14,508.61 L851.14,508.61
M833.14,526.95 L851.14,526.95 '/></g>
</g>
<g id="gnuplot_plot_30" ><title>gnuplot_plot_30</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb( 86, 180, 233)' fill-opacity = '0.250000' points = '924.42,553.41 937.76,553.41 937.76,553.15 924.42,553.15 '/>
</g>
<path stroke='rgb( 86, 180, 233)' d='M924.42,553.41 L937.76,553.41 L937.76,553.15 L924.42,553.15 L924.42,553.41 Z '/> <path stroke='rgb( 86, 180, 233)' d='M924.42,553.15 L937.76,553.15 M931.09,553.67 L931.09,553.41 M931.09,553.15 L931.09,552.89 M922.09,552.89 L940.09,552.89
M922.09,553.67 L940.09,553.67 '/></g>
</g>
<g id="gnuplot_plot_31" ><title>gnuplot_plot_31</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(695.97,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>urxvt</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '704.36,22.50 746.92,22.50 746.92,13.50 704.36,13.50 '/>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '138.73,554.20 152.09,554.20 152.09,553.67 138.73,553.67 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M138.73,554.20 L152.09,554.20 L152.09,553.67 L138.73,553.67 L138.73,554.20 Z '/> <path stroke='rgb(230, 159, 0)' d='M138.73,553.93 L152.09,553.93 M145.41,554.20 M145.41,553.67 L145.41,552.89 M136.41,552.89 L154.41,552.89 M136.41,554.20
L154.41,554.20 '/></g>
</g>
<g id="gnuplot_plot_32" ><title>gnuplot_plot_32</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '227.68,217.56 241.02,217.56 241.02,100.98 227.68,100.98 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M227.68,217.56 L241.02,217.56 L241.02,100.98 L227.68,100.98 L227.68,217.56 Z '/> <path stroke='rgb(230, 159, 0)' d='M227.68,176.95 L241.02,176.95 M234.35,273.88 L234.35,217.56 M234.35,100.98 L234.35,76.09 M225.35,76.09 L243.35,76.09
M225.35,273.88 L243.35,273.88 '/></g>
</g>
<g id="gnuplot_plot_33" ><title>gnuplot_plot_33</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '316.62,554.72 329.98,554.72 329.98,554.46 316.62,554.46 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M316.62,554.72 L329.98,554.72 L329.98,554.46 L316.62,554.46 L316.62,554.72 Z '/> <path stroke='rgb(230, 159, 0)' d='M316.62,554.72 L329.98,554.72 M323.30,554.98 L323.30,554.72 M323.30,554.46 L323.30,554.20 M314.30,554.20 L332.30,554.20
M314.30,554.98 L332.30,554.98 '/></g>
</g>
<g id="gnuplot_plot_34" ><title>gnuplot_plot_34</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '405.57,525.51 418.91,525.51 418.91,520.40 405.57,520.40 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M405.57,525.51 L418.91,525.51 L418.91,520.40 L405.57,520.40 L405.57,525.51 Z '/> <path stroke='rgb(230, 159, 0)' d='M405.57,523.68 L418.91,523.68 M412.24,531.93 L412.24,525.51 M412.24,520.40 L412.24,516.47 M403.24,516.47 L421.24,516.47
M403.24,531.93 L421.24,531.93 '/></g>
</g>
<g id="gnuplot_plot_35" ><title>gnuplot_plot_35</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '494.52,522.24 507.86,522.24 507.86,518.57 494.52,518.57 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M494.52,522.24 L507.86,522.24 L507.86,518.57 L494.52,518.57 L494.52,522.24 Z '/> <path stroke='rgb(230, 159, 0)' d='M494.52,519.35 L507.86,519.35 M501.19,527.48 L501.19,522.24 M501.19,518.57 L501.19,516.21 M492.19,516.21 L510.19,516.21
M492.19,527.48 L510.19,527.48 '/></g>
</g>
<g id="gnuplot_plot_36" ><title>gnuplot_plot_36</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '583.46,513.59 596.80,513.59 596.80,506.12 583.46,506.12 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M583.46,513.59 L596.80,513.59 L596.80,506.12 L583.46,506.12 L583.46,513.59 Z '/> <path stroke='rgb(230, 159, 0)' d='M583.46,510.97 L596.80,510.97 M590.13,515.69 L590.13,513.59 M590.13,506.12 L590.13,495.25 M581.13,495.25 L599.13,495.25
M581.13,515.69 L599.13,515.69 '/></g>
</g>
<g id="gnuplot_plot_37" ><title>gnuplot_plot_37</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '672.41,554.72 685.75,554.72 685.75,553.93 672.41,553.93 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M672.41,554.72 L685.75,554.72 L685.75,553.93 L672.41,553.93 L672.41,554.72 Z '/> <path stroke='rgb(230, 159, 0)' d='M672.41,554.46 L685.75,554.46 M679.08,554.98 L679.08,554.72 M679.08,553.93 L679.08,553.15 M670.08,553.15 L688.08,553.15
M670.08,554.98 L688.08,554.98 '/></g>
</g>
<g id="gnuplot_plot_38" ><title>gnuplot_plot_38</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '761.35,438.40 774.69,438.40 774.69,430.81 761.35,430.81 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M761.35,438.40 L774.69,438.40 L774.69,430.81 L761.35,430.81 L761.35,438.40 Z '/> <path stroke='rgb(230, 159, 0)' d='M761.35,434.21 L774.69,434.21 M768.02,446.00 L768.02,438.40 M768.02,430.81 L768.02,427.14 M759.02,427.14 L777.02,427.14
M759.02,446.00 L777.02,446.00 '/></g>
</g>
<g id="gnuplot_plot_39" ><title>gnuplot_plot_39</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(230, 159, 0)' fill-opacity = '0.250000' points = '850.30,480.58 863.64,480.58 863.64,470.89 850.30,470.89 '/>
</g>
<path stroke='rgb(230, 159, 0)' d='M850.30,480.58 L863.64,480.58 L863.64,470.89 L850.30,470.89 L850.30,480.58 Z '/> <path stroke='rgb(230, 159, 0)' d='M850.30,476.39 L863.64,476.39 M856.97,484.51 L856.97,480.58 M856.97,470.89 L856.97,464.86 M847.97,464.86 L865.97,464.86
M847.97,484.51 L865.97,484.51 '/></g>
</g>
<g id="gnuplot_plot_40" ><title>gnuplot_plot_40</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_41" ><title>gnuplot_plot_41</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g transform="translate(847.60,21.90)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>xterm</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(240, 228, 66)' fill-opacity = '0.250000' points = '855.99,22.50 898.55,22.50 898.55,13.50 855.99,13.50 '/>
<polygon fill = 'rgb(240, 228, 66)' fill-opacity = '0.250000' points = '153.56,222.01 166.90,222.01 166.90,215.07 153.56,215.07 '/>
</g>
<path stroke='rgb(240, 228, 66)' d='M153.56,222.01 L166.90,222.01 L166.90,215.07 L153.56,215.07 L153.56,222.01 Z '/> <path stroke='rgb(240, 228, 66)' d='M153.56,215.59 L166.90,215.59 M160.23,226.99 L160.23,222.01 M160.23,215.07 L160.23,214.94 M151.23,214.94 L169.23,214.94
M151.23,226.99 L169.23,226.99 '/></g>
</g>
<g id="gnuplot_plot_42" ><title>gnuplot_plot_42</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_43" ><title>gnuplot_plot_43</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(240, 228, 66)' fill-opacity = '0.250000' points = '331.45,532.71 344.79,532.71 344.79,528.26 331.45,528.26 '/>
</g>
<path stroke='rgb(240, 228, 66)' d='M331.45,532.71 L344.79,532.71 L344.79,528.26 L331.45,528.26 L331.45,532.71 Z '/> <path stroke='rgb(240, 228, 66)' d='M331.45,532.19 L344.79,532.19 M338.12,537.17 L338.12,532.71 M338.12,528.26 L338.12,521.97 M329.12,521.97 L347.12,521.97
M329.12,537.17 L347.12,537.17 '/></g>
</g>
<g id="gnuplot_plot_44" ><title>gnuplot_plot_44</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_45" ><title>gnuplot_plot_45</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_46" ><title>gnuplot_plot_46</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_47" ><title>gnuplot_plot_47</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g stroke='none' shape-rendering='crispEdges'>
<polygon fill = 'rgb(240, 228, 66)' fill-opacity = '0.250000' points = '687.23,483.73 700.57,483.73 700.57,477.44 687.23,477.44 '/>
</g>
<path stroke='rgb(240, 228, 66)' d='M687.23,483.73 L700.57,483.73 L700.57,477.44 L687.23,477.44 L687.23,483.73 Z '/> <path stroke='rgb(240, 228, 66)' d='M687.23,480.32 L700.57,480.32 M693.90,483.73 M693.90,477.44 L693.90,476.91 M684.90,476.91 L702.90,476.91 M684.90,483.73
L702.90,483.73 '/></g>
</g>
<g id="gnuplot_plot_48" ><title>gnuplot_plot_48</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_49" ><title>gnuplot_plot_49</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g id="gnuplot_plot_50" ><title>gnuplot_plot_50</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
<g fill="none" color="#FFFFFF" stroke="rgb(240, 228, 66)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="black" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M80.92,36.01 L80.92,559.96 L974.82,559.96 L974.82,36.01 L80.92,36.01 Z '/></g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 43 KiB

View file

@ -5,20 +5,10 @@
All benchmarks are done using [vtebench](https://github.com/alacritty/vtebench):
```sh
vtebench -h $(tput lines) -w $(tput cols) -b 104857600 alt-screen-random-write > ~/alt-random
vtebench -c -h $(tput lines) -w $(tput cols) -b 104857600 alt-screen-random-write > ~/alt-random-colors
vtebench -h $(tput lines) -w $(tput cols) -b 10485760 scrolling > ~/scrolling
vtebench -h $(tput lines) -w $(tput cols) -b 104857600 scrolling --fill-lines > ~/scrolling-filled-lines
vtebench -h $(tput lines) -w $(tput cols) -b 10485760 unicode-random-write > ~/unicode-random
./target/release/vtebench -b ./benchmarks --dat /tmp/<terminal>
```
They were "executed" using [benchmark.py](../scripts/benchmark.py),
which will load each file into memory, and then print it to the
terminal. This is done **20** times for each test. Then it calculates
the _mean_ and _standard deviation_ for each test.
## 2021-03-20
## 2021-06-25
### System
@ -40,14 +30,21 @@ Scrollback: 10000 lines
### Results
| Benchmark (times in ms) | Foot (GCC+PGO) 1.8.0 | Foot 1.8.0 | Alacritty 0.8.0 | URxvt 9.26 | XTerm 368 |
|-------------------------------|---------------------:|-----------:|----------------:|-----------:|----------:|
| cursor motion | 12.93 | 15.37 | 26.47 | 23.41 | 1304.00 |
| dense cells | 39.16 | 47.19 | 87.26 | 9110.00 | 10883.00 |
| light cells | 5.34 | 6.42 | 12.76 | 16.00 | 60.00 |
| scrollling | 144.26 | 139.93 | 133.98 | 117.52 | 3772.67 |
| scrolling bottom region | 130.81 | 125.34 | 116.10 | 117.31 | 3574.67 |
| scrolling bottom small region | 142.46 | 127.52 | 127.32 | 135.18 | 3572.67 |
| scrolling fullscreen | 5.43 | 5.27 | 12.06 | 11.97 | 118.62 |
| scrolling top region | 129.05 | 120.24 | 121.65 | 341.70 | 3567.33 |
| scrolling top small region | 121.59 | 109.82 | 137.03 | 219.96 | 3558.67 |
| unicode | 12.03 | 11.95 | 13.94 | 667.67 | 4905.67 |
| Benchmark | Foot (GCC+PGO) 1.7.0.r2 | Foot 1.7.0.r2 | Alacritty 0.7.2 | URxvt 9.22 | XTerm 366 |
|------------------------|------------------------:|--------------:|-------------------:|---------------:|---------------:|
| alt-random | 0.382s ±0.003 | 0.550s ±0.007 | 0.995s ±0.010 | 1.201s ±0.006 | 12.756s ±0.045 |
| alt-random-colors | 0.380s ±0.002 | 0.543s ±0.003 | 1.017s ±0.013 | 1.399s ±0.018 | 11.591s ±0.141 |
| scrolling | 1.302s ±0.019 | 1.284s ±0.052 | 1.107s ±0.028 | 1.097s ±0.015 | 37.537s ±0.121 |
| scrolling-filled-lines | 0.646s ±0.016 | 0.610s ±0.003 | 1.290s ±0.012 | 1.325s ±0.037 | 6.817s ±0.084 |
| unicode-random | 0.167s ±0.001 | 0.276s ±0.445 | 0.097s ±0.002 [^1] | 18.032s ±0.334 | 29.731s ±3.746 |
![Graph of benchmark results for a beefy desktop system](benchmark-results-desktop.svg)
## 2021-03-20
@ -73,32 +70,17 @@ Scrollback=10000 lines
### Results
| Benchmark | Foot (GCC+PGO) 1.7.0.r2 | Foot (no PGO) 1.7.0.r2 | Alacritty 0.7.2 | URxvt 9.22 | St 0.8.4 | XTerm 366 |
|------------------------|------------------------:|-----------------------:|-------------------:|-----------------:|--------------:|----------------:|
| alt-random | 0.714s ±0.047 | 0.900s ±0.041 | 1.586s ±0.045 | 1.684s ±0.034 | 2.054s ±0.121 | 37.205s ±0.252 |
| alt-random-colors | 0.736s ±0.054 | 0.950s ±0.082 | 1.565s ±0.043 | 2.150s ±0.137 | 2.195s ±0.154 | 33.112s ±0.167 |
| scrolling | 1.593s ±0.070 | 1.559s ±0.055 | 1.517s ±0.079 | 1.462s ±0.052 | 3.308s ±0.133 | 134.432s ±0.436 |
| scrolling-filled-lines | 1.178s ±0.044 | 1.309s ±0.045 | 2.281s ±0.086 | 2.044s ±0.060 | 2.732s ±0.056 | 20.753s ±0.067 |
| unicode-random | 0.349s ±0.009 | 0.352s ±0.007 | 0.148s ±0.010 [^1] | 19.090s ±0.363 | crashed | 15.579s ±0.093 |
| Benchmark (times in ms) | Foot (GCC+PGO) 1.8.0 | Foot 1.8.0 | Alacritty 0.8.0 | URxvt 9.26 | XTerm 368 |
|-------------------------------|---------------------:|-----------:|----------------:|-----------:|----------:|
| cursor motion | 14.49 | 16.60 | 26.89 | 23.45 | 1303.38 |
| dense cells | 41.00 | 52.45 | 92.02 | 1486.57 | 11957.00 |
| light cells | 7.97 | 8.54 | 21.43 | 20.45 | 111.96 |
| scrollling | 158.85 | 158.90 | 148.06 | 138.98 | 10083.00 |
| scrolling bottom region | 153.83 | 151.38 | 142.13 | 151.30 | 9988.50 |
| scrolling bottom small region | 143.51 | 141.46 | 162.03 | 192.37 | 9938.00 |
| scrolling fullscreen | 11.56 | 11.75 | 22.96 | 21.49 | 295.40 |
| scrolling top region | 148.96 | 148.18 | 155.05 | 482.05 | 10036.00 |
| scrolling top small region | 144.26 | 149.76 | 159.40 | 321.69 | 9942.50 |
| unicode | 21.02 | 22.09 | 25.79 | 14959.00 | 88697.00 |
[^1]: [Alacritty and "unicode-random"](#alacritty-and-unicode-random)
# Alacritty and "unicode-random"
Alacritty is actually **really** slow at rendering this (whether it is
fallback fonts in general, emojis, or something else, I don't know).
I believe the reason it finishes the benchmark so quickly is because
it reads from the PTY in a separate thread, into a larger receive
buffer which is then consumed by the main thread. This allows the
client program to write its output much faster since it is no longer
stalling on a blocked PTY.
This means Alacritty only needs to render a couple of frames since it
can reach the final VT state almost immediately.
On the other hand, `cat`:ing the `unicode-random` test file in an
endless loop, or just manually scrolling up after the benchmark is
done is **slow**, which besides being felt (input lag), can be seen by
setting `debug.render_timer = true` in `alacritty.yml`.
![Graph of benchmark results for a laptop](benchmark-results-laptop.svg)

View file

@ -126,7 +126,7 @@ the foot command line
This option can only be used in combination with *-s*,*--server*.
*-d*,*--log-level*={*info*,*warning*,*error*}
*-d*,*--log-level*={*info*,*warning*,*error*,*none*}
Log level, used both for log output on stderr as well as
syslog. Default: _info_.

View file

@ -997,8 +997,26 @@ any of these options.
but is necessary to not break cursor synchronization with the
application running in foot.
See also: *grapheme-width-method*.
Default: _no_
*grapheme-width-method*
Selects which method to use when calculating the width
(i.e. number of columns) of a grapheme cluster. One of
*double-width* and *wcswidth*.
*wcswidth* simply adds together the individual width of all
codepoints making up the cluster.
*double-width* does the same, but limits the maximum number of
columns to 2. This is more correct, but is likely to break
applications since applications typically use *wcswidth*(3)
internally to calculate the width. This results in cursor
de-synchronization issues.
Default: _double-width_
*max-shm-pool-size-mb*
This option controls the amount of virtual address space used by
the pixmap memory to which the terminal screen content is

View file

@ -69,7 +69,7 @@ terminal has terminated.
Override an option set in the configuration file. If _SECTION_ is not
given, defaults to _main_.
*-d*,*--log-level*={*info*,*warning*,*error*}
*-d*,*--log-level*={*info*,*warning*,*error*,*none*}
Log level, used both for log output on stderr as well as
syslog. Default: _info_.

View file

@ -24,6 +24,7 @@ foot+base|foot base fragment,
xenl,
AX,
XT,
Tc,
cols#80,
it#8,
lines#24,
@ -255,6 +256,8 @@ foot+base|foot base fragment,
rs1=\Ec,
rs2=\E[!p\E[?3;4l\E[4l\E>,
sc=\E7,
setrgbb=\E[48\:2\:\:%p1%d\:%p2%d\:%p3%dm,
setrgbf=\E[38\:2\:\:%p1%d\:%p2%d\:%p3%dm,
sgr0=\E(B\E[m,
sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
sitm=\E[3m,

View file

@ -529,8 +529,6 @@ convert_key_bindings(const struct config *conf, struct seat *seat)
{
for (size_t i = 0; i < conf->bindings.key.count; i++) {
const struct config_key_binding *binding = &conf->bindings.key.arr[i];
if (binding->action == BIND_ACTION_NONE)
continue;
convert_key_binding(seat, binding, &seat->kbd.bindings.key);
}
}
@ -540,8 +538,6 @@ convert_search_bindings(const struct config *conf, struct seat *seat)
{
for (size_t i = 0; i < conf->bindings.search.count; i++) {
const struct config_key_binding *binding = &conf->bindings.search.arr[i];
if (binding->action == BIND_ACTION_SEARCH_NONE)
continue;
convert_key_binding(seat, binding, &seat->kbd.bindings.search);
}
}
@ -551,10 +547,6 @@ convert_url_bindings(const struct config *conf, struct seat *seat)
{
for (size_t i = 0; i < conf->bindings.url.count; i++) {
const struct config_key_binding *binding = &conf->bindings.url.arr[i];
#if 0
if (binding->action == BIND_ACTION_URL_NONE)
continue;
#endif
convert_key_binding(seat, binding, &seat->kbd.bindings.url);
}
}

88
log.c
View file

@ -3,6 +3,7 @@
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -15,15 +16,19 @@
static bool colorize = false;
static bool do_syslog = true;
static enum log_class log_level = LOG_CLASS_INFO;
static enum log_class log_level = LOG_CLASS_NONE;
static const char log_level_map[][8] = {
[LOG_CLASS_ERROR] = "error",
[LOG_CLASS_WARNING] = "warning",
[LOG_CLASS_INFO] = "info",
#if defined(_DEBUG)
[LOG_CLASS_DEBUG] = "debug",
#endif
static const struct {
const char name[8];
const char log_prefix[7];
uint8_t color;
int syslog_equivalent;
} log_level_map[] = {
[LOG_CLASS_NONE] = {"none", "none", 5, -1},
[LOG_CLASS_ERROR] = {"error", " err", 31, LOG_ERR},
[LOG_CLASS_WARNING] = {"warning", "warn", 33, LOG_WARNING},
[LOG_CLASS_INFO] = {"info", "info", 97, LOG_INFO},
[LOG_CLASS_DEBUG] = {"debug", " dbg", 36, LOG_DEBUG},
};
void
@ -35,20 +40,14 @@ log_init(enum log_colorize _colorize, bool _do_syslog,
[LOG_FACILITY_DAEMON] = LOG_DAEMON,
};
static const int level_map[] = {
[LOG_CLASS_ERROR] = LOG_ERR,
[LOG_CLASS_WARNING] = LOG_WARNING,
[LOG_CLASS_INFO] = LOG_INFO,
[LOG_CLASS_DEBUG] = LOG_DEBUG,
};
colorize = _colorize == LOG_COLORIZE_NEVER ? false : _colorize == LOG_COLORIZE_ALWAYS ? true : isatty(STDERR_FILENO);
do_syslog = _do_syslog;
log_level = _log_level;
if (do_syslog) {
int slvl = log_level_map[_log_level].syslog_equivalent;
if (do_syslog && slvl != -1) {
openlog(NULL, /*LOG_PID*/0, facility_map[syslog_facility]);
setlogmask(LOG_UPTO(level_map[_log_level]));
setlogmask(LOG_UPTO(slvl));
}
}
@ -63,34 +62,31 @@ static void
_log(enum log_class log_class, const char *module, const char *file, int lineno,
const char *fmt, int sys_errno, va_list va)
{
xassert(log_class > LOG_CLASS_NONE);
xassert(log_class < ALEN(log_level_map));
if (log_class > log_level)
return;
const char *class = "abcd";
int class_clr = 0;
switch (log_class) {
case LOG_CLASS_ERROR: class = " err"; class_clr = 31; break;
case LOG_CLASS_WARNING: class = "warn"; class_clr = 33; break;
case LOG_CLASS_INFO: class = "info"; class_clr = 97; break;
case LOG_CLASS_DEBUG: class = " dbg"; class_clr = 36; break;
}
const char *prefix = log_level_map[log_class].log_prefix;
unsigned int class_clr = log_level_map[log_class].color;
char clr[16];
snprintf(clr, sizeof(clr), "\033[%dm", class_clr);
fprintf(stderr, "%s%s%s: ", colorize ? clr : "", class, colorize ? "\033[0m" : "");
xsnprintf(clr, sizeof(clr), "\033[%um", class_clr);
fprintf(stderr, "%s%s%s: ", colorize ? clr : "", prefix, colorize ? "\033[0m" : "");
if (colorize)
fprintf(stderr, "\033[2m");
fputs("\033[2m", stderr);
fprintf(stderr, "%s:%d: ", file, lineno);
if (colorize)
fprintf(stderr, "\033[0m");
fputs("\033[0m", stderr);
vfprintf(stderr, fmt, va);
if (sys_errno != 0)
fprintf(stderr, ": %s", strerror(sys_errno));
fprintf(stderr, "\n");
fputc('\n', stderr);
}
static void
@ -98,19 +94,14 @@ _sys_log(enum log_class log_class, const char *module,
const char UNUSED *file, int UNUSED lineno,
const char *fmt, int sys_errno, va_list va)
{
xassert(log_class > LOG_CLASS_NONE);
xassert(log_class < ALEN(log_level_map));
if (!do_syslog)
return;
/* Map our log level to syslog's level */
int level = -1;
switch (log_class) {
case LOG_CLASS_ERROR: level = LOG_ERR; break;
case LOG_CLASS_WARNING: level = LOG_WARNING; break;
case LOG_CLASS_INFO: level = LOG_INFO; break;
case LOG_CLASS_DEBUG: level = LOG_DEBUG; break;
}
xassert(level != -1);
int level = log_level_map[log_class].syslog_equivalent;
char msg[4096];
int n = vsnprintf(msg, sizeof(msg), fmt, va);
@ -185,14 +176,25 @@ log_errno_provided(enum log_class log_class, const char *module,
va_end(va);
}
static size_t
map_len(void)
{
size_t len = ALEN(log_level_map);
#ifndef _DEBUG
/* Exclude "debug" entry for non-debug builds */
len--;
#endif
return len;
}
int
log_level_from_string(const char *str)
{
if (unlikely(str[0] == '\0'))
return -1;
for (int i = 0, n = ALEN(log_level_map); i < n; i++)
if (strcmp(str, log_level_map[i]) == 0)
for (int i = 0, n = map_len(); i < n; i++)
if (strcmp(str, log_level_map[i].name) == 0)
return i;
return -1;
@ -205,8 +207,8 @@ log_level_string_hint(void)
if (buf[0] != '\0')
return buf;
for (size_t i = 0, pos = 0, n = ALEN(log_level_map); i < n; i++) {
const char *entry = log_level_map[i];
for (size_t i = 0, pos = 0, n = map_len(); i < n; i++) {
const char *entry = log_level_map[i].name;
const char *delim = (i + 1 < n) ? ", " : "";
pos += xsnprintf(buf + pos, sizeof(buf) - pos, "'%s'%s", entry, delim);
}

9
log.h
View file

@ -5,7 +5,14 @@
enum log_colorize { LOG_COLORIZE_NEVER, LOG_COLORIZE_ALWAYS, LOG_COLORIZE_AUTO };
enum log_facility { LOG_FACILITY_USER, LOG_FACILITY_DAEMON };
enum log_class { LOG_CLASS_ERROR, LOG_CLASS_WARNING, LOG_CLASS_INFO, LOG_CLASS_DEBUG };
enum log_class {
LOG_CLASS_NONE,
LOG_CLASS_ERROR,
LOG_CLASS_WARNING,
LOG_CLASS_INFO,
LOG_CLASS_DEBUG
};
void log_init(enum log_colorize colorize, bool do_syslog,
enum log_facility syslog_facility, enum log_class log_level);

49
main.c
View file

@ -61,27 +61,27 @@ print_usage(const char *prog_name)
"Usage: %s [OPTIONS...] command [ARGS...]\n"
"\n"
"Options:\n"
" -c,--config=PATH load configuration from PATH ($XDG_CONFIG_HOME/foot/foot.ini)\n"
" -C,--check-config verify configuration, exit with 0 if ok, otherwise exit with 1\n"
" -o,--override=[section.]key=value override configuration option\n"
" -f,--font=FONT comma separated list of fonts in fontconfig format (monospace)\n"
" -t,--term=TERM value to set the environment variable TERM to (%s)\n"
" -T,--title=TITLE initial window title (foot)\n"
" -a,--app-id=ID window application ID (foot)\n"
" -m,--maximized start in maximized mode\n"
" -F,--fullscreen start in fullscreen mode\n"
" -L,--login-shell start shell as a login shell\n"
" -D,--working-directory=DIR directory to start in (CWD)\n"
" -w,--window-size-pixels=WIDTHxHEIGHT initial width and height, in pixels\n"
" -W,--window-size-chars=WIDTHxHEIGHT initial width and height, in characters\n"
" -s,--server[=PATH] run as a server (use 'footclient' to start terminals).\n"
" Without PATH, $XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock will be used.\n"
" -H,--hold remain open after child process exits\n"
" -p,--print-pid=FILE|FD print PID to file or FD (only applicable in server mode)\n"
" -d,--log-level={info|warning|error} log level (info)\n"
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
" -s,--log-no-syslog disable syslog logging (only applicable in server mode)\n"
" -v,--version show the version number and quit\n",
" -c,--config=PATH load configuration from PATH ($XDG_CONFIG_HOME/foot/foot.ini)\n"
" -C,--check-config verify configuration, exit with 0 if ok, otherwise exit with 1\n"
" -o,--override=[section.]key=value override configuration option\n"
" -f,--font=FONT comma separated list of fonts in fontconfig format (monospace)\n"
" -t,--term=TERM value to set the environment variable TERM to (%s)\n"
" -T,--title=TITLE initial window title (foot)\n"
" -a,--app-id=ID window application ID (foot)\n"
" -m,--maximized start in maximized mode\n"
" -F,--fullscreen start in fullscreen mode\n"
" -L,--login-shell start shell as a login shell\n"
" -D,--working-directory=DIR directory to start in (CWD)\n"
" -w,--window-size-pixels=WIDTHxHEIGHT initial width and height, in pixels\n"
" -W,--window-size-chars=WIDTHxHEIGHT initial width and height, in characters\n"
" -s,--server[=PATH] run as a server (use 'footclient' to start terminals).\n"
" Without PATH, $XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock will be used.\n"
" -H,--hold remain open after child process exits\n"
" -p,--print-pid=FILE|FD print PID to file or FD (only applicable in server mode)\n"
" -d,--log-level={info|warning|error|none} log level (info)\n"
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
" -s,--log-no-syslog disable syslog logging (only applicable in server mode)\n"
" -v,--version show the version number and quit\n",
prog_name, prog_name, DEFAULT_TERM);
}
@ -383,11 +383,14 @@ main(int argc, char *const *argv)
log_init(log_colorize, as_server && log_syslog,
as_server ? LOG_FACILITY_DAEMON : LOG_FACILITY_USER, log_level);
_Static_assert(LOG_CLASS_ERROR + 1 == FCFT_LOG_CLASS_ERROR,
_Static_assert((int)LOG_CLASS_ERROR == (int)FCFT_LOG_CLASS_ERROR,
"fcft log level enum offset");
_Static_assert((int)LOG_COLORIZE_ALWAYS == (int)FCFT_LOG_COLORIZE_ALWAYS,
"fcft colorize enum mismatch");
fcft_log_init((enum fcft_log_colorize)log_colorize, as_server && log_syslog, log_level + 1);
fcft_log_init(
(enum fcft_log_colorize)log_colorize,
as_server && log_syslog,
(enum fcft_log_class)log_level);
argc -= optind;
argv += optind;

View file

@ -617,7 +617,7 @@ render_cell(struct terminal *term, pixman_image_t *pix,
*/
if (term->conf->tweak.allow_overflowing_double_width_glyphs &&
((glyph_count > 0 &&
glyphs[0]->cols == 1 &&
cell_cols == 1 &&
glyphs[0]->width >= term->cell_width * 15 / 10 &&
glyphs[0]->width < 3 * term->cell_width &&
col < term->cols - 1) ||

View file

@ -1425,10 +1425,10 @@ term_destroy(struct terminal *term)
}
mtx_unlock(&term->render.workers.lock);
urls_reset(term);
free(term->vt.osc.data);
free(term->vt.osc8.uri);
grid_free(&term->normal);
grid_free(&term->alt);
composed_free(term->composed);
@ -1471,9 +1471,11 @@ term_destroy(struct terminal *term)
sixel_fini(term);
urls_reset(term);
term_ime_reset(term);
grid_free(&term->normal);
grid_free(&term->alt);
free(term->foot_exe);
free(term->cwd);

34
vt.c
View file

@ -639,10 +639,10 @@ action_utf8_print(struct terminal *term, wchar_t wc)
#if defined(FOOT_GRAPHEME_CLUSTERING)
if (grapheme_clustering) {
/* Check if we're on a grapheme cluster break */
/* Note: utf8proc fails to ZWJ */
if (utf8proc_grapheme_break_stateful(last, wc, &term->vt.grapheme_state) &&
last != 0x200d /* ZWJ */)
if (utf8proc_grapheme_break_stateful(
last, wc, &term->vt.grapheme_state))
{
term_reset_grapheme_state(term);
goto out;
}
}
@ -682,6 +682,7 @@ action_utf8_print(struct terminal *term, wchar_t wc)
{
wc = precomposed;
width = precomposed_width;
term_reset_grapheme_state(term);
goto out;
}
}
@ -746,6 +747,7 @@ action_utf8_print(struct terminal *term, wchar_t wc)
* character chains. Fall through here and print the
* current zero-width character to the current cell */
LOG_WARN("maximum number of composed characters reached");
term_reset_grapheme_state(term);
goto out;
}
@ -762,28 +764,36 @@ action_utf8_print(struct terminal *term, wchar_t wc)
(wanted_count - 2) * sizeof(new_cc->chars[0]));
}
int grapheme_width = composed != NULL ? composed->width : base_width;
const int grapheme_width =
composed != NULL ? composed->width : base_width;
if (wc == 0xfe0f && grapheme_width < 2)
grapheme_width = 2;
else
grapheme_width += width;
new_cc->width = grapheme_width;
switch (term->conf->tweak.grapheme_width_method) {
case GRAPHEME_WIDTH_DOUBLE:
if (unlikely(wc == 0xfe0f))
width = 2;
new_cc->width = min(grapheme_width + width, 2);
break;
case GRAPHEME_WIDTH_WCSWIDTH:
new_cc->width = grapheme_width + width;
break;
}
term->composed_count++;
composed_insert(&term->composed, new_cc);
wc = CELL_COMB_CHARS_LO + key;
width = grapheme_width;
width = new_cc->width;
xassert(wc >= CELL_COMB_CHARS_LO);
xassert(wc <= CELL_COMB_CHARS_HI);
goto out;
}
}
} else
term_reset_grapheme_state(term);
out:
term_reset_grapheme_state(term);
if (width > 0)
term_print(term, wc, width);
}