@ -54,6 +54,16 @@ terminal_destroy(struct terminal *terminal);
static int
static int
terminal_run ( struct terminal * terminal , const char * path ) ;
terminal_run ( struct terminal * terminal , const char * path ) ;
# define TERMINAL_DRAW_SINGLE_WIDE_CHARACTERS \
" ! \" #$%&'()*+,-./ " \
" 0123456789 " \
" :;<=>?@ " \
" ABCDEFGHIJKLMNOPQRSTUVWXYZ " \
" [ \\ ]^_` " \
" abcdefghijklmnopqrstuvwxyz " \
" {|}~ " \
" "
# define MOD_SHIFT 0x01
# define MOD_SHIFT 0x01
# define MOD_ALT 0x02
# define MOD_ALT 0x02
# define MOD_CTRL 0x04
# define MOD_CTRL 0x04
@ -407,6 +417,7 @@ struct terminal {
struct color_scheme * color_scheme ;
struct color_scheme * color_scheme ;
struct terminal_color color_table [ 256 ] ;
struct terminal_color color_table [ 256 ] ;
cairo_font_extents_t extents ;
cairo_font_extents_t extents ;
double average_width ;
cairo_scaled_font_t * font_normal , * font_bold ;
cairo_scaled_font_t * font_normal , * font_bold ;
uint32_t hide_cursor_serial ;
uint32_t hide_cursor_serial ;
@ -760,12 +771,12 @@ resize_handler(struct widget *widget,
int32_t columns , rows , m ;
int32_t columns , rows , m ;
m = 2 * terminal - > margin ;
m = 2 * terminal - > margin ;
columns = ( width - m ) / ( int32_t ) terminal - > extents . max_x_advance ;
columns = ( width - m ) / ( int32_t ) terminal - > average_width ;
rows = ( height - m ) / ( int32_t ) terminal - > extents . height ;
rows = ( height - m ) / ( int32_t ) terminal - > extents . height ;
if ( ! window_is_fullscreen ( terminal - > window ) & &
if ( ! window_is_fullscreen ( terminal - > window ) & &
! window_is_maximized ( terminal - > window ) ) {
! window_is_maximized ( terminal - > window ) ) {
width = columns * terminal - > extents . max_x_advance + m ;
width = columns * terminal - > average_width + m ;
height = rows * terminal - > extents . height + m ;
height = rows * terminal - > extents . height + m ;
widget_set_size ( terminal - > widget , width , height ) ;
widget_set_size ( terminal - > widget , width , height ) ;
}
}
@ -783,7 +794,7 @@ terminal_resize(struct terminal *terminal, int columns, int rows)
return ;
return ;
m = 2 * terminal - > margin ;
m = 2 * terminal - > margin ;
width = columns * terminal - > extents . max_x_advance + m ;
width = columns * terminal - > average_width + m ;
height = rows * terminal - > extents . height + m ;
height = rows * terminal - > extents . height + m ;
frame_set_child_size ( terminal - > widget , width , height ) ;
frame_set_child_size ( terminal - > widget , width , height ) ;
@ -930,6 +941,7 @@ redraw_handler(struct widget *widget, void *data)
double d ;
double d ;
struct glyph_run run ;
struct glyph_run run ;
cairo_font_extents_t extents ;
cairo_font_extents_t extents ;
double average_width ;
surface = window_get_surface ( terminal - > window ) ;
surface = window_get_surface ( terminal - > window ) ;
widget_get_allocation ( terminal - > widget , & allocation ) ;
widget_get_allocation ( terminal - > widget , & allocation ) ;
@ -946,7 +958,8 @@ redraw_handler(struct widget *widget, void *data)
cairo_set_scaled_font ( cr , terminal - > font_normal ) ;
cairo_set_scaled_font ( cr , terminal - > font_normal ) ;
extents = terminal - > extents ;
extents = terminal - > extents ;
side_margin = ( allocation . width - terminal - > width * extents . max_x_advance ) / 2 ;
average_width = terminal - > average_width ;
side_margin = ( allocation . width - terminal - > width * average_width ) / 2 ;
top_margin = ( allocation . height - terminal - > height * extents . height ) / 2 ;
top_margin = ( allocation . height - terminal - > height * extents . height ) / 2 ;
cairo_set_line_width ( cr , 1.0 ) ;
cairo_set_line_width ( cr , 1.0 ) ;
@ -962,11 +975,11 @@ redraw_handler(struct widget *widget, void *data)
continue ;
continue ;
terminal_set_color ( terminal , cr , attr . attr . bg ) ;
terminal_set_color ( terminal , cr , attr . attr . bg ) ;
cairo_move_to ( cr , col * extents . max_x_advance ,
cairo_move_to ( cr , col * average_width ,
row * extents . height ) ;
row * extents . height ) ;
cairo_rel_line_to ( cr , extents . max_x_advance , 0 ) ;
cairo_rel_line_to ( cr , average_width , 0 ) ;
cairo_rel_line_to ( cr , 0 , extents . height ) ;
cairo_rel_line_to ( cr , 0 , extents . height ) ;
cairo_rel_line_to ( cr , - extents . max_x_advance , 0 ) ;
cairo_rel_line_to ( cr , - average_width , 0 ) ;
cairo_close_path ( cr ) ;
cairo_close_path ( cr ) ;
cairo_fill ( cr ) ;
cairo_fill ( cr ) ;
}
}
@ -984,12 +997,12 @@ redraw_handler(struct widget *widget, void *data)
glyph_run_flush ( & run , attr ) ;
glyph_run_flush ( & run , attr ) ;
text_x = col * extents . max_x_advance ;
text_x = col * average_width ;
text_y = extents . ascent + row * extents . height ;
text_y = extents . ascent + row * extents . height ;
if ( attr . attr . a & ATTRMASK_UNDERLINE ) {
if ( attr . attr . a & ATTRMASK_UNDERLINE ) {
terminal_set_color ( terminal , cr , attr . attr . fg ) ;
terminal_set_color ( terminal , cr , attr . attr . fg ) ;
cairo_move_to ( cr , text_x , ( double ) text_y + 1.5 ) ;
cairo_move_to ( cr , text_x , ( double ) text_y + 1.5 ) ;
cairo_line_to ( cr , text_x + extents . max_x_advance , ( double ) text_y + 1.5 ) ;
cairo_line_to ( cr , text_x + average_width , ( double ) text_y + 1.5 ) ;
cairo_stroke ( cr ) ;
cairo_stroke ( cr ) ;
}
}
@ -1005,11 +1018,11 @@ redraw_handler(struct widget *widget, void *data)
d = 0.5 ;
d = 0.5 ;
cairo_set_line_width ( cr , 1 ) ;
cairo_set_line_width ( cr , 1 ) ;
cairo_move_to ( cr , terminal - > column * extents . max_x_advance + d ,
cairo_move_to ( cr , terminal - > column * average_width + d ,
terminal - > row * extents . height + d ) ;
terminal - > row * extents . height + d ) ;
cairo_rel_line_to ( cr , extents . max_x_advance - 2 * d , 0 ) ;
cairo_rel_line_to ( cr , average_width - 2 * d , 0 ) ;
cairo_rel_line_to ( cr , 0 , extents . height - 2 * d ) ;
cairo_rel_line_to ( cr , 0 , extents . height - 2 * d ) ;
cairo_rel_line_to ( cr , - extents . max_x_advance + 2 * d , 0 ) ;
cairo_rel_line_to ( cr , - average_width + 2 * d , 0 ) ;
cairo_close_path ( cr ) ;
cairo_close_path ( cr ) ;
cairo_stroke ( cr ) ;
cairo_stroke ( cr ) ;
@ -1022,7 +1035,7 @@ redraw_handler(struct widget *widget, void *data)
if ( terminal - > send_cursor_position ) {
if ( terminal - > send_cursor_position ) {
cursor_x = side_margin + allocation . x +
cursor_x = side_margin + allocation . x +
terminal - > column * extents . max_x_advance ;
terminal - > column * average_width ;
cursor_y = top_margin + allocation . y +
cursor_y = top_margin + allocation . y +
terminal - > row * extents . height ;
terminal - > row * extents . height ;
window_set_text_cursor_position ( terminal - > window ,
window_set_text_cursor_position ( terminal - > window ,
@ -2371,7 +2384,7 @@ recompute_selection(struct terminal *terminal)
int cw , ch ;
int cw , ch ;
union utf8_char * data ;
union utf8_char * data ;
cw = terminal - > extents . max_x_advance ;
cw = terminal - > average_width ;
ch = terminal - > extents . height ;
ch = terminal - > extents . height ;
widget_get_allocation ( terminal - > widget , & allocation ) ;
widget_get_allocation ( terminal - > widget , & allocation ) ;
width = terminal - > width * cw ;
width = terminal - > width * cw ;
@ -2527,12 +2540,17 @@ output_handler(struct window *window, struct output *output, int enter,
window_schedule_redraw ( window ) ;
window_schedule_redraw ( window ) ;
}
}
# ifndef howmany
# define howmany(x, y) (((x) + ((y) - 1)) / (y))
# endif
static struct terminal *
static struct terminal *
terminal_create ( struct display * display )
terminal_create ( struct display * display )
{
{
struct terminal * terminal ;
struct terminal * terminal ;
cairo_surface_t * surface ;
cairo_surface_t * surface ;
cairo_t * cr ;
cairo_t * cr ;
cairo_text_extents_t text_extents ;
terminal = malloc ( sizeof * terminal ) ;
terminal = malloc ( sizeof * terminal ) ;
if ( terminal = = NULL )
if ( terminal = = NULL )
@ -2584,6 +2602,15 @@ terminal_create(struct display *display)
cairo_scaled_font_reference ( terminal - > font_normal ) ;
cairo_scaled_font_reference ( terminal - > font_normal ) ;
cairo_font_extents ( cr , & terminal - > extents ) ;
cairo_font_extents ( cr , & terminal - > extents ) ;
/* Compute the average ascii glyph width */
cairo_text_extents ( cr , TERMINAL_DRAW_SINGLE_WIDE_CHARACTERS ,
& text_extents ) ;
terminal - > average_width = howmany
( text_extents . width ,
strlen ( TERMINAL_DRAW_SINGLE_WIDE_CHARACTERS ) ) ;
terminal - > average_width = ceil ( terminal - > average_width ) ;
cairo_destroy ( cr ) ;
cairo_destroy ( cr ) ;
cairo_surface_destroy ( surface ) ;
cairo_surface_destroy ( surface ) ;