diff --git a/kitty/core_text.m b/kitty/core_text.m index 8c54ba69b..ff1be554f 100644 --- a/kitty/core_text.m +++ b/kitty/core_text.m @@ -366,9 +366,11 @@ cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, u CGRect bounds_without_leading = CTLineGetBoundsWithOptions(line, kCTLineBoundsExcludeTypographicLeading); CGFloat typographic_ascent, typographic_descent, typographic_leading; CTLineGetTypographicBounds(line, &typographic_ascent, &typographic_descent, &typographic_leading); - CGFloat bounds_ascent = bounds_without_leading.size.height + bounds_without_leading.origin.y - OPT(adjust_baseline); - *baseline = (unsigned int)floor(bounds_ascent + 0.5); *cell_height = MAX(4u, (unsigned int)ceilf(line_height)); + CGFloat bounds_ascent = bounds_without_leading.size.height + bounds_without_leading.origin.y; + if (OPT(adjust_baseline_px) != 0) bounds_ascent -= OPT(adjust_baseline_px); + if (OPT(adjust_baseline_frac) != 0) bounds_ascent -= *cell_height * OPT(adjust_baseline_frac); + *baseline = (unsigned int)floor(bounds_ascent + 0.5); // Not sure if we should add this to bounds ascent and then round it or add // it to already rounded baseline and round again. *underline_position = (unsigned int)floor(bounds_ascent - self->underline_position + 0.5); diff --git a/kitty/freetype.c b/kitty/freetype.c index d6a53a836..95d83c3a1 100644 --- a/kitty/freetype.c +++ b/kitty/freetype.c @@ -307,12 +307,15 @@ cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, u Face *self = (Face*)s; *cell_width = calc_cell_width(self); *cell_height = calc_cell_height(self, true); - *baseline = font_units_to_pixels_y(self, self->ascender); - *underline_position = MIN(*cell_height - 1, (unsigned int)font_units_to_pixels_y(self, MAX(0, self->ascender - self->underline_position))); + int baseline_offset = 0; + if (OPT(adjust_baseline_px) != 0) baseline_offset = OPT(adjust_baseline_px); + if (OPT(adjust_baseline_frac) != 0) baseline_offset = (int)(*cell_height * OPT(adjust_baseline_frac)); + *baseline = font_units_to_pixels_y(self, self->ascender) - baseline_offset; + *underline_position = MIN(*cell_height - 1, (unsigned int)MAX(0, font_units_to_pixels_y(self, MAX(0, self->ascender - self->underline_position)) - baseline_offset)); *underline_thickness = MAX(1, font_units_to_pixels_y(self, self->underline_thickness)); if (self->strikethrough_position != 0) { - *strikethrough_position = MIN(*cell_height - 1, (unsigned int)font_units_to_pixels_y(self, MAX(0, self->ascender - self->strikethrough_position))); + *strikethrough_position = MIN(*cell_height - 1, (unsigned int)MAX(0, font_units_to_pixels_y(self, MAX(0, self->ascender - self->strikethrough_position)) - baseline_offset)); } else { *strikethrough_position = (unsigned int)floor(*baseline * 0.65); } diff --git a/kitty/options/definition.py b/kitty/options/definition.py index e22475c9f..a9f9cce12 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -95,11 +95,14 @@ opt('adjust_column_width', '0', ) opt('adjust_baseline', '0', - option_type='int', ctype='int', + option_type='adjust_baseline', ctype='!adjust_baseline', add_to_default=False, long_text=''' -Adjust the baseline position of each character (in pixels) on macOS. A positive -number moves all characters up, and a negative number moves them down. +Adjust the baseline position of each character. You can use either +a number, which is interpreted as pixels or a percentage (number followed by %), +which is interpreted as the percentage of the line height. A positive +value moves all characters up, and a negative value moves them down. +The underline and strikethrough positions are adjusted accordingly. ''' ) diff --git a/kitty/options/parse.py b/kitty/options/parse.py index b03396912..c84cb4f41 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -7,16 +7,16 @@ from kitty.conf.utils import ( unit_float ) from kitty.options.utils import ( - active_tab_title_template, adjust_line_height, allow_hyperlinks, allow_remote_control, - box_drawing_scale, clear_all_shortcuts, clipboard_control, config_or_absolute_path, copy_on_select, - cursor_text_color, deprecated_hide_window_decorations_aliases, - deprecated_macos_show_window_title_in_menubar_alias, deprecated_send_text, disable_ligatures, - edge_width, env, font_features, hide_window_decorations, kitten_alias, macos_option_as_alt, - macos_titlebar_color, optional_edge_width, parse_map, parse_mouse_map, resize_draw_strategy, - scrollback_lines, scrollback_pager_history_size, symbol_map, tab_activity_symbol, tab_bar_edge, - tab_bar_margin_height, tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator, - tab_title_template, to_cursor_shape, to_font_size, to_layout_names, to_modifiers, url_prefixes, - url_style, window_border_width, window_size + active_tab_title_template, adjust_baseline, adjust_line_height, allow_hyperlinks, + allow_remote_control, box_drawing_scale, clear_all_shortcuts, clipboard_control, + config_or_absolute_path, copy_on_select, cursor_text_color, + deprecated_hide_window_decorations_aliases, deprecated_macos_show_window_title_in_menubar_alias, + deprecated_send_text, disable_ligatures, edge_width, env, font_features, hide_window_decorations, + kitten_alias, macos_option_as_alt, macos_titlebar_color, optional_edge_width, parse_map, + parse_mouse_map, resize_draw_strategy, scrollback_lines, scrollback_pager_history_size, symbol_map, + tab_activity_symbol, tab_bar_edge, tab_bar_margin_height, tab_bar_min_tabs, tab_fade, + tab_font_style, tab_separator, tab_title_template, to_cursor_shape, to_font_size, to_layout_names, + to_modifiers, url_prefixes, url_style, window_border_width, window_size ) @@ -38,7 +38,7 @@ class Parser: ans['active_tab_title_template'] = active_tab_title_template(val) def adjust_baseline(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: - ans['adjust_baseline'] = int(val) + ans['adjust_baseline'] = adjust_baseline(val) def adjust_column_width(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['adjust_column_width'] = adjust_line_height(val) diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h index d18dcb7a2..7fa2db6b1 100644 --- a/kitty/options/to-c-generated.h +++ b/kitty/options/to-c-generated.h @@ -59,7 +59,7 @@ convert_from_opts_adjust_column_width(PyObject *py_opts, Options *opts) { static void convert_from_python_adjust_baseline(PyObject *val, Options *opts) { - opts->adjust_baseline = PyLong_AsLong(val); + adjust_baseline(val, opts); } static void diff --git a/kitty/options/to-c.h b/kitty/options/to-c.h index 4de83e3b8..2875f1d23 100644 --- a/kitty/options/to-c.h +++ b/kitty/options/to-c.h @@ -162,4 +162,6 @@ static void adjust_line_height(PyObject *al, Options *opts) { read_adjust(adjust_line_height); } static void adjust_column_width(PyObject *al, Options *opts) { read_adjust(adjust_column_width); } +static void +adjust_baseline(PyObject *al, Options *opts) { read_adjust(adjust_baseline); } #undef read_adjust diff --git a/kitty/options/types.py b/kitty/options/types.py index 9d3e14431..6b3632ecb 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -436,7 +436,7 @@ class Options: active_tab_font_style: typing.Tuple[bool, bool] = (True, True) active_tab_foreground: Color = Color(red=0, green=0, blue=0) active_tab_title_template: typing.Optional[str] = None - adjust_baseline: int = 0 + adjust_baseline: typing.Union[int, float] = 0 adjust_column_width: typing.Union[int, float] = 0 adjust_line_height: typing.Union[int, float] = 0 allow_hyperlinks: int = 1 diff --git a/kitty/options/utils.py b/kitty/options/utils.py index cf57697d2..5f20390d1 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -424,6 +424,16 @@ def adjust_line_height(x: str) -> Union[int, float]: return int(x) +def adjust_baseline(x: str) -> Union[int, float]: + if x.endswith('%'): + ans = float(x[:-1].strip()) / 100.0 + if abs(ans) > 1: + log_error('Percentage adjustments of the baseline cannot exceed 100%') + return 0 + return ans + return int(x) + + def to_font_size(x: str) -> float: return max(MINIMUM_FONT_SIZE, float(x)) diff --git a/kitty/state.h b/kitty/state.h index 5fd909084..66f6f70ec 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -40,9 +40,8 @@ typedef struct { unsigned int macos_option_as_alt; float macos_thicken_font; WindowTitleIn macos_show_window_title_in; - int adjust_line_height_px, adjust_column_width_px; - float adjust_line_height_frac, adjust_column_width_frac; - int adjust_baseline; + int adjust_line_height_px, adjust_column_width_px, adjust_baseline_px; + float adjust_line_height_frac, adjust_column_width_frac, adjust_baseline_frac; float background_opacity, dim_opacity; char* background_image;