mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-09 10:06:20 -05:00
Merge branch 'fcft-v2'
This commit is contained in:
commit
f1336a0902
8 changed files with 130 additions and 42 deletions
|
|
@ -33,6 +33,12 @@
|
|||
(https://codeberg.org/dnkl/foot/issues/4)
|
||||
* memfd sealing failures are no longer fatal errors.
|
||||
* Selection to no longer be cleared on resize.
|
||||
* The current monitor's subpixel order (RGB/BGR/V-RGB/V-BGR) is
|
||||
preferred over FontConfig's `rgba` property. Only if the monitor's
|
||||
subpixel order is `unknown` is FontConfig's `rgba` property used. If
|
||||
the subpixel order is `none`, then grayscale antialiasing is
|
||||
used. The subpixel order is ignored if antialiasing has been
|
||||
disabled.
|
||||
|
||||
|
||||
### Deprecated
|
||||
|
|
|
|||
4
PKGBUILD
4
PKGBUILD
|
|
@ -4,8 +4,8 @@ pkgrel=1
|
|||
arch=('x86_64')
|
||||
url=https://codeberg.org/dnkl/foot
|
||||
license=(mit)
|
||||
makedepends=('meson' 'ninja' 'scdoc' 'python' 'ncurses' 'wayland-protocols' 'tllist>=1.0.0')
|
||||
depends=('libxkbcommon' 'wayland' 'pixman' 'fcft>=1.1.1')
|
||||
makedepends=('meson' 'ninja' 'scdoc' 'python' 'ncurses' 'wayland-protocols' 'tllist>=1.0.1')
|
||||
depends=('libxkbcommon' 'wayland' 'pixman' 'fcft>=2.0.0')
|
||||
source=()
|
||||
|
||||
pkgver() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
project('foot', 'c',
|
||||
version: '1.2.3',
|
||||
license: 'MIT',
|
||||
meson_version: '>=0.47.0',
|
||||
meson_version: '>=0.53.0',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
'warning_level=1',
|
||||
|
|
@ -57,8 +57,8 @@ wayland_client = dependency('wayland-client')
|
|||
wayland_cursor = dependency('wayland-cursor')
|
||||
xkb = dependency('xkbcommon')
|
||||
|
||||
tllist = dependency('tllist', version: '>=1.0.0', fallback: ['tllist', 'tllist'])
|
||||
fcft = dependency('fcft', version: ['>=1.1.1', '<1.2.0'], fallback: ['fcft', 'fcft'])
|
||||
tllist = dependency('tllist', version: '>=1.0.1', fallback: 'tllist')
|
||||
fcft = dependency('fcft', version: ['>=2.0.0', '<2.1.0'], fallback: 'fcft')
|
||||
|
||||
wayland_protocols_datadir = wayland_protocols.get_pkgconfig_variable('pkgdatadir')
|
||||
|
||||
|
|
|
|||
22
render.c
22
render.c
|
|
@ -196,7 +196,7 @@ static const struct wp_presentation_feedback_listener presentation_feedback_list
|
|||
.discarded = &discarded,
|
||||
};
|
||||
|
||||
static struct font *
|
||||
static struct fcft_font *
|
||||
attrs_to_font(const struct terminal *term, const struct attributes *attrs)
|
||||
{
|
||||
int idx = attrs->italic << 1 | attrs->bold;
|
||||
|
|
@ -263,7 +263,7 @@ draw_unfocused_block(const struct terminal *term, pixman_image_t *pix,
|
|||
|
||||
static void
|
||||
draw_bar(const struct terminal *term, pixman_image_t *pix,
|
||||
const struct font *font,
|
||||
const struct fcft_font *font,
|
||||
const pixman_color_t *color, int x, int y)
|
||||
{
|
||||
int baseline = y + font_baseline(term) - term->fonts[0]->ascent;
|
||||
|
|
@ -276,7 +276,7 @@ draw_bar(const struct terminal *term, pixman_image_t *pix,
|
|||
|
||||
static void
|
||||
draw_underline(const struct terminal *term, pixman_image_t *pix,
|
||||
const struct font *font,
|
||||
const struct fcft_font *font,
|
||||
const pixman_color_t *color, int x, int y, int cols)
|
||||
{
|
||||
pixman_image_fill_rectangles(
|
||||
|
|
@ -288,7 +288,7 @@ draw_underline(const struct terminal *term, pixman_image_t *pix,
|
|||
|
||||
static void
|
||||
draw_strikeout(const struct terminal *term, pixman_image_t *pix,
|
||||
const struct font *font,
|
||||
const struct fcft_font *font,
|
||||
const pixman_color_t *color, int x, int y, int cols)
|
||||
{
|
||||
pixman_image_fill_rectangles(
|
||||
|
|
@ -300,7 +300,7 @@ draw_strikeout(const struct terminal *term, pixman_image_t *pix,
|
|||
|
||||
static void
|
||||
draw_cursor(const struct terminal *term, const struct cell *cell,
|
||||
const struct font *font, pixman_image_t *pix, pixman_color_t *fg,
|
||||
const struct fcft_font *font, pixman_image_t *pix, pixman_color_t *fg,
|
||||
const pixman_color_t *bg, int x, int y, int cols)
|
||||
{
|
||||
pixman_color_t cursor_color;
|
||||
|
|
@ -402,9 +402,9 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
color_dim_for_search(&bg);
|
||||
}
|
||||
|
||||
struct font *font = attrs_to_font(term, &cell->attrs);
|
||||
const struct glyph *glyph = cell->wc != 0
|
||||
? font_glyph_for_wc(font, cell->wc, term->colors.alpha == 0xffff)
|
||||
struct fcft_font *font = attrs_to_font(term, &cell->attrs);
|
||||
const struct fcft_glyph *glyph = cell->wc != 0
|
||||
? fcft_glyph_rasterize(font, cell->wc, term->font_subpixel)
|
||||
: NULL;
|
||||
|
||||
int cell_cols = glyph != NULL ? max(1, glyph->cols) : 1;
|
||||
|
|
@ -1527,7 +1527,7 @@ render_search_box(struct terminal *term)
|
|||
PIXMAN_OP_SRC, buf->pix, &transparent,
|
||||
1, &(pixman_rectangle16_t){0, 0, width - visible_width, height});
|
||||
|
||||
struct font *font = term->fonts[0];
|
||||
struct fcft_font *font = term->fonts[0];
|
||||
int x = width - visible_width + margin;
|
||||
int y = margin;
|
||||
pixman_color_t fg = color_hex_to_pixman(term->colors.table[0]);
|
||||
|
|
@ -1553,7 +1553,9 @@ render_search_box(struct terminal *term)
|
|||
if (i == term->search.cursor)
|
||||
draw_bar(term, buf->pix, font, &fg, x, y);
|
||||
|
||||
const struct glyph *glyph = font_glyph_for_wc(font, term->search.buf[i], true);
|
||||
const struct fcft_glyph *glyph = fcft_glyph_rasterize(
|
||||
font, term->search.buf[i], true);
|
||||
|
||||
if (glyph == NULL)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
126
terminal.c
126
terminal.c
|
|
@ -512,17 +512,17 @@ initialize_render_workers(struct terminal *term)
|
|||
}
|
||||
|
||||
static bool
|
||||
term_set_fonts(struct terminal *term, struct font *fonts[static 4])
|
||||
term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4])
|
||||
{
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
assert(fonts[i] != NULL);
|
||||
|
||||
font_destroy(term->fonts[i]);
|
||||
fcft_destroy(term->fonts[i]);
|
||||
term->fonts[i] = fonts[i];
|
||||
}
|
||||
|
||||
term->cell_width = term->fonts[0]->space_x_advance > 0
|
||||
? term->fonts[0]->space_x_advance : term->fonts[0]->max_x_advance;
|
||||
term->cell_width = term->fonts[0]->space_advance.x > 0
|
||||
? term->fonts[0]->space_advance.x : term->fonts[0]->max_advance.x;
|
||||
term->cell_height = max(term->fonts[0]->height,
|
||||
term->fonts[0]->ascent + term->fonts[0]->descent);
|
||||
LOG_INFO("cell width=%d, height=%d", term->cell_width, term->cell_height);
|
||||
|
|
@ -579,9 +579,53 @@ get_font_dpi(const struct terminal *term)
|
|||
return dpi;
|
||||
}
|
||||
|
||||
static enum fcft_subpixel
|
||||
get_font_subpixel(const struct terminal *term)
|
||||
{
|
||||
if (term->colors.alpha != 0xffff) {
|
||||
/* Can't do subpixel rendering on transparent background */
|
||||
return FCFT_SUBPIXEL_NONE;
|
||||
}
|
||||
|
||||
enum wl_output_subpixel wl_subpixel;
|
||||
|
||||
/*
|
||||
* Wayland doesn't tell us *which* part of the surface that goes
|
||||
* on a specific output, only whether the surface is mapped to an
|
||||
* output or not.
|
||||
*
|
||||
* Thus, when determining which subpixel mode to use, we can't do
|
||||
* much but select *an* output. So, we pick the first one.
|
||||
*
|
||||
* If we're not mapped at all, we pick the first available
|
||||
* monitor, and hope that's where we'll eventually get mapped.
|
||||
*
|
||||
* If there aren't any monitors we use the "default" subpixel
|
||||
* mode.
|
||||
*/
|
||||
|
||||
if (tll_length(term->window->on_outputs) > 0)
|
||||
wl_subpixel = tll_front(term->window->on_outputs)->subpixel;
|
||||
else if (tll_length(term->wl->monitors) > 0)
|
||||
wl_subpixel = tll_front(term->wl->monitors).subpixel;
|
||||
else
|
||||
wl_subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
|
||||
|
||||
switch (wl_subpixel) {
|
||||
case WL_OUTPUT_SUBPIXEL_UNKNOWN: return FCFT_SUBPIXEL_DEFAULT;
|
||||
case WL_OUTPUT_SUBPIXEL_NONE: return FCFT_SUBPIXEL_NONE;
|
||||
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB: return FCFT_SUBPIXEL_HORIZONTAL_RGB;
|
||||
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR: return FCFT_SUBPIXEL_HORIZONTAL_BGR;
|
||||
case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB: return FCFT_SUBPIXEL_VERTICAL_RGB;
|
||||
case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR: return FCFT_SUBPIXEL_VERTICAL_BGR;
|
||||
}
|
||||
|
||||
return FCFT_SUBPIXEL_DEFAULT;
|
||||
}
|
||||
|
||||
static bool
|
||||
load_fonts_from_conf(const struct terminal *term, const struct config *conf,
|
||||
struct font *fonts[static 4])
|
||||
struct fcft_font *fonts[static 4])
|
||||
{
|
||||
const size_t count = tll_length(conf->fonts);
|
||||
const char *names[count];
|
||||
|
|
@ -598,15 +642,15 @@ load_fonts_from_conf(const struct terminal *term, const struct config *conf,
|
|||
|
||||
fonts[0] = fonts[1] = fonts[2] = fonts[3] = NULL;
|
||||
bool ret =
|
||||
(fonts[0] = font_from_name(count, names, attrs0)) != NULL &&
|
||||
(fonts[1] = font_from_name(count, names, attrs1)) != NULL &&
|
||||
(fonts[2] = font_from_name(count, names, attrs2)) != NULL &&
|
||||
(fonts[3] = font_from_name(count, names, attrs3)) != NULL;
|
||||
(fonts[0] = fcft_from_name(count, names, attrs0)) != NULL &&
|
||||
(fonts[1] = fcft_from_name(count, names, attrs1)) != NULL &&
|
||||
(fonts[2] = fcft_from_name(count, names, attrs2)) != NULL &&
|
||||
(fonts[3] = fcft_from_name(count, names, attrs3)) != NULL;
|
||||
|
||||
if (!ret) {
|
||||
LOG_ERR("failed to load primary fonts");
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
font_destroy(fonts[i]);
|
||||
fcft_destroy(fonts[i]);
|
||||
fonts[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -686,6 +730,9 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
|||
.ptmx_buffer = tll_init(),
|
||||
.font_dpi = 0,
|
||||
.font_adjustments = 0,
|
||||
.font_subpixel = (conf->colors.alpha == 0xffff /* Can't do subpixel rendering on transparent background */
|
||||
? FCFT_SUBPIXEL_DEFAULT
|
||||
: FCFT_SUBPIXEL_NONE),
|
||||
.cursor_keys_mode = CURSOR_KEYS_NORMAL,
|
||||
.keypad_keys_mode = KEYPAD_NUMERICAL,
|
||||
.auto_margin = true,
|
||||
|
|
@ -795,6 +842,8 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
|||
if (!term_font_dpi_changed(term))
|
||||
goto err;
|
||||
|
||||
term->font_subpixel = get_font_subpixel(term);
|
||||
|
||||
term_set_window_title(term, conf->title);
|
||||
|
||||
/* Let the Wayland backend know we exist */
|
||||
|
|
@ -998,7 +1047,7 @@ term_destroy(struct terminal *term)
|
|||
tll_free_and_free(term->window_title_stack, free);
|
||||
|
||||
for (size_t i = 0; i < sizeof(term->fonts) / sizeof(term->fonts[0]); i++)
|
||||
font_destroy(term->fonts[i]);
|
||||
fcft_destroy(term->fonts[i]);
|
||||
|
||||
free(term->search.buf);
|
||||
|
||||
|
|
@ -1233,18 +1282,18 @@ term_reset(struct terminal *term, bool hard)
|
|||
static bool
|
||||
term_font_size_adjust(struct terminal *term, double amount)
|
||||
{
|
||||
struct font *fonts[4] = {
|
||||
font_size_adjust(term->fonts[0], amount),
|
||||
font_size_adjust(term->fonts[1], amount),
|
||||
font_size_adjust(term->fonts[2], amount),
|
||||
font_size_adjust(term->fonts[3], amount),
|
||||
struct fcft_font *fonts[4] = {
|
||||
fcft_size_adjust(term->fonts[0], amount),
|
||||
fcft_size_adjust(term->fonts[1], amount),
|
||||
fcft_size_adjust(term->fonts[2], amount),
|
||||
fcft_size_adjust(term->fonts[3], amount),
|
||||
};
|
||||
|
||||
if (fonts[0] == NULL || fonts[1] == NULL ||
|
||||
fonts[2] == NULL || fonts[3] == NULL)
|
||||
{
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
font_destroy(fonts[i]);
|
||||
fcft_destroy(fonts[i]);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1275,7 +1324,7 @@ term_font_size_decrease(struct terminal *term)
|
|||
bool
|
||||
term_font_size_reset(struct terminal *term)
|
||||
{
|
||||
struct font *fonts[4];
|
||||
struct fcft_font *fonts[4];
|
||||
if (!load_fonts_from_conf(term, term->conf, fonts))
|
||||
return false;
|
||||
|
||||
|
|
@ -1294,7 +1343,7 @@ term_font_dpi_changed(struct terminal *term)
|
|||
LOG_DBG("DPI changed (%u -> %u): reloading fonts", term->font_dpi, dpi);
|
||||
term->font_dpi = dpi;
|
||||
|
||||
struct font *fonts[4];
|
||||
struct fcft_font *fonts[4];
|
||||
if (!load_fonts_from_conf(term, term->conf, fonts))
|
||||
return false;
|
||||
|
||||
|
|
@ -1305,25 +1354,25 @@ term_font_dpi_changed(struct terminal *term)
|
|||
|
||||
double amount = term->font_adjustments * 0.5;
|
||||
|
||||
struct font *adjusted_fonts[4] = {
|
||||
font_size_adjust(fonts[0], amount),
|
||||
font_size_adjust(fonts[1], amount),
|
||||
font_size_adjust(fonts[2], amount),
|
||||
font_size_adjust(fonts[3], amount),
|
||||
struct fcft_font *adjusted_fonts[4] = {
|
||||
fcft_size_adjust(fonts[0], amount),
|
||||
fcft_size_adjust(fonts[1], amount),
|
||||
fcft_size_adjust(fonts[2], amount),
|
||||
fcft_size_adjust(fonts[3], amount),
|
||||
};
|
||||
|
||||
if (adjusted_fonts[0] == NULL || adjusted_fonts[1] == NULL ||
|
||||
adjusted_fonts[2] == NULL || adjusted_fonts[3] == NULL)
|
||||
{
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
font_destroy(adjusted_fonts[i]);
|
||||
fcft_destroy(adjusted_fonts[i]);
|
||||
|
||||
/* At least use the newly re-loaded default fonts */
|
||||
term->font_adjustments = 0;
|
||||
return term_set_fonts(term, fonts);
|
||||
} else {
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
font_destroy(fonts[i]);
|
||||
fcft_destroy(fonts[i]);
|
||||
return term_set_fonts(term, adjusted_fonts);
|
||||
}
|
||||
|
||||
|
|
@ -1331,6 +1380,31 @@ term_font_dpi_changed(struct terminal *term)
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
term_font_subpixel_changed(struct terminal *term)
|
||||
{
|
||||
enum fcft_subpixel subpixel = get_font_subpixel(term);
|
||||
|
||||
if (term->font_subpixel == subpixel)
|
||||
return;
|
||||
|
||||
#if defined(_DEBUG) && LOG_ENABLE_DBG
|
||||
static const char *const str[] = {
|
||||
[FCFT_SUBPIXEL_ORDER_DEFAULT] = "default",
|
||||
[FCFT_SUBPIXEL_ORDER_NONE] = "disabled",
|
||||
[FCFT_SUBPIXEL_ORDER_HORIZONTAL_RGB] = "RGB",
|
||||
[FCFT_SUBPIXEL_ORDER_HORIZONTAL_BGR] = "BGR",
|
||||
[FCFT_SUBPIXEL_ORDER_VERTICAL_RGB] = "V-RGB",
|
||||
[FCFT_SUBPIXEL_ORDER_VERTICAL_BGR] = "V-BGR",
|
||||
};
|
||||
#endif
|
||||
|
||||
LOG_DBG("subpixel mode changed: %s -> %s", str[term->font_subpixel], str[subpixel]);
|
||||
term->font_subpixel = subpixel;
|
||||
term_damage_view(term);
|
||||
render_refresh(term);
|
||||
}
|
||||
|
||||
void
|
||||
term_damage_rows(struct terminal *term, int start, int end)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -214,9 +214,10 @@ struct terminal {
|
|||
struct grid alt;
|
||||
struct grid *grid;
|
||||
|
||||
struct font *fonts[4];
|
||||
struct fcft_font *fonts[4];
|
||||
int font_dpi;
|
||||
int font_adjustments;
|
||||
enum fcft_subpixel font_subpixel;
|
||||
|
||||
tll(struct ptmx_buffer) ptmx_buffer;
|
||||
|
||||
|
|
@ -445,6 +446,8 @@ bool term_font_size_increase(struct terminal *term);
|
|||
bool term_font_size_decrease(struct terminal *term);
|
||||
bool term_font_size_reset(struct terminal *term);
|
||||
bool term_font_dpi_changed(struct terminal *term);
|
||||
void term_font_subpixel_changed(struct terminal *term);
|
||||
|
||||
|
||||
void term_damage_rows(struct terminal *term, int start, int end);
|
||||
void term_damage_rows_in_view(struct terminal *term, int start, int end);
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ update_term_for_output_change(struct terminal *term)
|
|||
|
||||
render_resize(term, term->width / term->scale, term->height / term->scale);
|
||||
term_font_dpi_changed(term);
|
||||
term_font_subpixel_changed(term);
|
||||
wayl_reload_cursor_theme(term->wl, term);
|
||||
}
|
||||
|
||||
|
|
@ -193,6 +194,7 @@ output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y,
|
|||
mon->inch = sqrt(pow(mon->dim.mm.width, 2) + pow(mon->dim.mm.height, 2)) * 0.03937008;
|
||||
mon->make = make != NULL ? strdup(make) : NULL;
|
||||
mon->model = model != NULL ? strdup(model) : NULL;
|
||||
mon->subpixel = subpixel;
|
||||
output_update_ppi(mon);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ struct monitor {
|
|||
|
||||
int scale;
|
||||
float refresh;
|
||||
enum wl_output_subpixel subpixel;
|
||||
|
||||
char *make;
|
||||
char *model;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue