mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-10 04:27:45 -05:00
render: implement 'underline'
This commit is contained in:
parent
441337645a
commit
d93ca2f654
4 changed files with 86 additions and 34 deletions
42
main.c
42
main.c
|
|
@ -10,6 +10,7 @@
|
|||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <cairo-ft.h>
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-cursor.h>
|
||||
#include <xdg-shell.h>
|
||||
|
|
@ -349,23 +350,48 @@ main(int argc, char *const *argv)
|
|||
thrd_t keyboard_repeater_id;
|
||||
thrd_create(&keyboard_repeater_id, &keyboard_repeater, &term);
|
||||
|
||||
term.fonts[0] = font_from_name(conf.font);
|
||||
if (term.fonts[0] == NULL)
|
||||
term.fonts[0].font = font_from_name(conf.font);
|
||||
if (term.fonts[0].font == NULL)
|
||||
goto out;
|
||||
|
||||
{
|
||||
char fname[1024];
|
||||
snprintf(fname, sizeof(fname), "%s:style=bold", conf.font);
|
||||
term.fonts[1] = font_from_name(fname);
|
||||
term.fonts[1].font = font_from_name(fname);
|
||||
|
||||
snprintf(fname, sizeof(fname), "%s:style=italic", conf.font);
|
||||
term.fonts[2] = font_from_name(fname);
|
||||
term.fonts[2].font = font_from_name(fname);
|
||||
|
||||
snprintf(fname, sizeof(fname), "%s:style=bold italic", conf.font);
|
||||
term.fonts[3] = font_from_name(fname);
|
||||
term.fonts[3].font = font_from_name(fname);
|
||||
}
|
||||
|
||||
cairo_scaled_font_extents(term.fonts[0], &term.fextents);
|
||||
/* Underline position and size */
|
||||
for (size_t i = 0; i < sizeof(term.fonts) / sizeof(term.fonts[0]); i++) {
|
||||
struct font *f = &term.fonts[i];
|
||||
|
||||
if (f->font == NULL)
|
||||
continue;
|
||||
|
||||
FT_Face ft_face = cairo_ft_scaled_font_lock_face(f->font);
|
||||
|
||||
double x_scale = ft_face->size->metrics.x_scale / 65526.;
|
||||
f->underline.position = ft_face->underline_position * x_scale / 64.;
|
||||
f->underline.thickness = ft_face->underline_thickness * x_scale / 64.;
|
||||
|
||||
if (f->underline.position == 0.) {
|
||||
double descent = ft_face->size->metrics.descender / 64;
|
||||
f->underline.position = descent / 2.;
|
||||
f->underline.thickness = fabs(round(descent / 5.));
|
||||
}
|
||||
|
||||
LOG_DBG("underline: pos=%f, thick=%f",
|
||||
f->underline.position, f->underline.thickness);
|
||||
|
||||
cairo_ft_scaled_font_unlock_face(f->font);
|
||||
}
|
||||
|
||||
cairo_scaled_font_extents(term.fonts[0].font, &term.fextents);
|
||||
term.cell_width = (int)ceil(term.fextents.max_x_advance);
|
||||
term.cell_height = (int)ceil(term.fextents.height);
|
||||
|
||||
|
|
@ -699,8 +725,8 @@ out:
|
|||
free(term.alt.rows);
|
||||
|
||||
for (size_t i = 0; i < sizeof(term.fonts) / sizeof(term.fonts[0]); i++) {
|
||||
if (term.fonts[i] != NULL)
|
||||
cairo_scaled_font_destroy(term.fonts[i]);
|
||||
if (term.fonts[i].font != NULL)
|
||||
cairo_scaled_font_destroy(term.fonts[i].font);
|
||||
}
|
||||
|
||||
if (term.ptmx != -1)
|
||||
|
|
|
|||
66
render.c
66
render.c
|
|
@ -15,11 +15,11 @@
|
|||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
cairo_scaled_font_t *
|
||||
const struct font *
|
||||
attrs_to_font(struct terminal *term, const struct attributes *attrs)
|
||||
{
|
||||
int idx = attrs->italic << 1 | attrs->bold;
|
||||
return term->fonts[idx];
|
||||
return &term->fonts[idx];
|
||||
}
|
||||
|
||||
struct glyph_sequence {
|
||||
|
|
@ -28,11 +28,7 @@ struct glyph_sequence {
|
|||
int count;
|
||||
|
||||
struct attributes attrs;
|
||||
#if 0
|
||||
struct rgb foreground;
|
||||
#else
|
||||
uint32_t foreground;
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct glyph_sequence gseq;
|
||||
|
|
@ -41,18 +37,18 @@ static void
|
|||
gseq_flush(struct terminal *term, struct buffer *buf)
|
||||
{
|
||||
struct rgb fg = {
|
||||
((gseq.foreground >> 16) & 0xff) / 255.0,
|
||||
((gseq.foreground >> 8) & 0xff) / 255.0,
|
||||
((gseq.foreground >> 0) & 0xff) / 255.0,
|
||||
((gseq.foreground >> 16) & 0xff) / 255.,
|
||||
((gseq.foreground >> 8) & 0xff) / 255.,
|
||||
((gseq.foreground >> 0) & 0xff) / 255.,
|
||||
};
|
||||
|
||||
if (gseq.attrs.dim) {
|
||||
fg.r /= 2.0;
|
||||
fg.g /= 2.0;
|
||||
fg.b /= 2.0;
|
||||
fg.r /= 2.;
|
||||
fg.g /= 2.;
|
||||
fg.b /= 2.;
|
||||
}
|
||||
|
||||
cairo_set_scaled_font(buf->cairo, attrs_to_font(term, &gseq.attrs));
|
||||
cairo_set_scaled_font(buf->cairo, attrs_to_font(term, &gseq.attrs)->font);
|
||||
cairo_set_source_rgb(buf->cairo, fg.r, fg.g, fg.b);
|
||||
cairo_show_glyphs(buf->cairo, gseq.glyphs, gseq.count);
|
||||
|
||||
|
|
@ -109,22 +105,44 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
|
|||
_background = swap;
|
||||
}
|
||||
|
||||
struct rgb background = {
|
||||
((_background >> 16) & 0xff) / 255.0,
|
||||
((_background >> 8) & 0xff) / 255.0,
|
||||
((_background >> 0) & 0xff) / 255.0,
|
||||
struct rgb foreground = {
|
||||
((_foreground >> 16) & 0xff) / 255.,
|
||||
((_foreground >> 8) & 0xff) / 255.,
|
||||
((_foreground >> 0) & 0xff) / 255.,
|
||||
};
|
||||
|
||||
struct rgb background = {
|
||||
((_background >> 16) & 0xff) / 255.,
|
||||
((_background >> 8) & 0xff) / 255.,
|
||||
((_background >> 0) & 0xff) / 255.,
|
||||
};
|
||||
|
||||
if (cell->attrs.dim) {
|
||||
foreground.r /= 2.;
|
||||
foreground.g /= 2.;
|
||||
foreground.b /= 2.;
|
||||
}
|
||||
|
||||
/* Background */
|
||||
cairo_set_source_rgb(buf->cairo, background.r, background.g, background.b);
|
||||
cairo_rectangle(buf->cairo, x, y, width, height);
|
||||
cairo_fill(buf->cairo);
|
||||
|
||||
if (cell->c[0] == '\0' || cell->c[0] == ' ')
|
||||
if (cell->c[0] == '\0' || cell->attrs.conceal)
|
||||
return;
|
||||
|
||||
if (cell->attrs.conceal)
|
||||
return;
|
||||
/* Underline */
|
||||
if (cell->attrs.underline) {
|
||||
const struct font *font = attrs_to_font(term, &cell->attrs);
|
||||
double width = font->underline.thickness;
|
||||
double y_under = y + term->cell_height + font->underline.position + width / 2.;
|
||||
|
||||
cairo_set_source_rgb(buf->cairo, foreground.r, foreground.g, foreground.b);
|
||||
cairo_set_line_width(buf->cairo, width);
|
||||
cairo_move_to(buf->cairo, x, y_under);
|
||||
cairo_line_to(buf->cairo, x + term->cell_width, y_under);
|
||||
cairo_stroke(buf->cairo);
|
||||
}
|
||||
|
||||
/*
|
||||
* cairo_show_glyphs() apparently works *much* faster when
|
||||
|
|
@ -151,7 +169,7 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
|
|||
= sizeof(gseq.glyphs) / sizeof(gseq.glyphs[0]) - gseq.count;
|
||||
|
||||
cairo_status_t status = cairo_scaled_font_text_to_glyphs(
|
||||
attrs_to_font(term, &cell->attrs), x, y + term->fextents.ascent,
|
||||
attrs_to_font(term, &cell->attrs)->font, x, y + term->fextents.ascent,
|
||||
cell->c, strnlen(cell->c, 4), &gseq.g, &new_glyphs,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
|
|
@ -256,9 +274,9 @@ grid_render(struct terminal *term)
|
|||
#else
|
||||
uint32_t _bg = !term->reverse ? term->background : term->foreground;
|
||||
struct rgb bg = {
|
||||
((_bg >> 16) & 0xff) / 255.0,
|
||||
((_bg >> 8) & 0xff) / 255.0,
|
||||
((_bg >> 0) & 0xff) / 255.0,
|
||||
((_bg >> 16) & 0xff) / 255.,
|
||||
((_bg >> 8) & 0xff) / 255.,
|
||||
((_bg >> 0) & 0xff) / 255.,
|
||||
};
|
||||
#endif
|
||||
cairo_set_source_rgb(buf->cairo, bg.r, bg.g, bg.b);
|
||||
|
|
|
|||
2
render.h
2
render.h
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "terminal.h"
|
||||
|
||||
cairo_scaled_font_t *attrs_to_font(
|
||||
const struct font *attrs_to_font(
|
||||
struct terminal *term, const struct attributes *attrs);
|
||||
|
||||
void grid_render(struct terminal *term);
|
||||
|
|
|
|||
10
terminal.h
10
terminal.h
|
|
@ -202,6 +202,14 @@ struct primary {
|
|||
uint32_t serial;
|
||||
};
|
||||
|
||||
struct font {
|
||||
cairo_scaled_font_t *font;
|
||||
struct {
|
||||
double position;
|
||||
double thickness;
|
||||
} underline;
|
||||
};
|
||||
|
||||
struct terminal {
|
||||
pid_t slave;
|
||||
int ptmx;
|
||||
|
|
@ -258,7 +266,7 @@ struct terminal {
|
|||
struct grid alt;
|
||||
struct grid *grid;
|
||||
|
||||
cairo_scaled_font_t *fonts[4];
|
||||
struct font fonts[4];
|
||||
cairo_font_extents_t fextents;
|
||||
|
||||
struct wayland wl;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue