mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
font: add cursor-height
metric, and adjust-
config for it.
This commit is contained in:
@ -241,16 +241,15 @@ const c = @cImport({
|
|||||||
/// `-100%`) can cause the terminal to be unusable. Use with caution and reason.
|
/// `-100%`) can cause the terminal to be unusable. Use with caution and reason.
|
||||||
///
|
///
|
||||||
/// Some values are clamped to minimum or maximum values. This can make it
|
/// Some values are clamped to minimum or maximum values. This can make it
|
||||||
/// appear that certain values are ignored. For example, the underline position
|
/// appear that certain values are ignored. For example, many `*-thickness`
|
||||||
/// is clamped to the height of a cell. If you set the underline position so
|
/// adjustments cannot go below 1px.
|
||||||
/// high that it extends beyond the bottom of the cell size, it will be clamped
|
|
||||||
/// to the bottom of the cell.
|
|
||||||
///
|
///
|
||||||
/// `adjust-cell-height` has some additional behaviors to describe:
|
/// `adjust-cell-height` has some additional behaviors to describe:
|
||||||
///
|
///
|
||||||
/// * The font will be centered vertically in the cell.
|
/// * The font will be centered vertically in the cell.
|
||||||
///
|
///
|
||||||
/// * The cursor will remain the same size as the font.
|
/// * The cursor will remain the same size as the font, but may be
|
||||||
|
/// adjusted separately with `adjust-cursor-height`.
|
||||||
///
|
///
|
||||||
/// * Powerline glyphs will be adjusted along with the cell height so
|
/// * Powerline glyphs will be adjusted along with the cell height so
|
||||||
/// that things like status lines continue to look aligned.
|
/// that things like status lines continue to look aligned.
|
||||||
@ -276,6 +275,9 @@ const c = @cImport({
|
|||||||
@"adjust-overline-thickness": ?MetricModifier = null,
|
@"adjust-overline-thickness": ?MetricModifier = null,
|
||||||
/// Thickness in pixels of the bar cursor and outlined rect cursor.
|
/// Thickness in pixels of the bar cursor and outlined rect cursor.
|
||||||
@"adjust-cursor-thickness": ?MetricModifier = null,
|
@"adjust-cursor-thickness": ?MetricModifier = null,
|
||||||
|
/// Height in pixels of the cursor. Currently applies to all cursor types:
|
||||||
|
/// bar, rect, and outlined rect.
|
||||||
|
@"adjust-cursor-height": ?MetricModifier = null,
|
||||||
/// Thickness in pixels of box drawing characters.
|
/// Thickness in pixels of box drawing characters.
|
||||||
@"adjust-box-thickness": ?MetricModifier = null,
|
@"adjust-box-thickness": ?MetricModifier = null,
|
||||||
|
|
||||||
|
@ -430,6 +430,7 @@ pub const DerivedConfig = struct {
|
|||||||
@"adjust-overline-position": ?Metrics.Modifier,
|
@"adjust-overline-position": ?Metrics.Modifier,
|
||||||
@"adjust-overline-thickness": ?Metrics.Modifier,
|
@"adjust-overline-thickness": ?Metrics.Modifier,
|
||||||
@"adjust-cursor-thickness": ?Metrics.Modifier,
|
@"adjust-cursor-thickness": ?Metrics.Modifier,
|
||||||
|
@"adjust-cursor-height": ?Metrics.Modifier,
|
||||||
@"adjust-box-thickness": ?Metrics.Modifier,
|
@"adjust-box-thickness": ?Metrics.Modifier,
|
||||||
@"freetype-load-flags": font.face.FreetypeLoadFlags,
|
@"freetype-load-flags": font.face.FreetypeLoadFlags,
|
||||||
|
|
||||||
@ -468,6 +469,7 @@ pub const DerivedConfig = struct {
|
|||||||
.@"adjust-overline-position" = config.@"adjust-overline-position",
|
.@"adjust-overline-position" = config.@"adjust-overline-position",
|
||||||
.@"adjust-overline-thickness" = config.@"adjust-overline-thickness",
|
.@"adjust-overline-thickness" = config.@"adjust-overline-thickness",
|
||||||
.@"adjust-cursor-thickness" = config.@"adjust-cursor-thickness",
|
.@"adjust-cursor-thickness" = config.@"adjust-cursor-thickness",
|
||||||
|
.@"adjust-cursor-height" = config.@"adjust-cursor-height",
|
||||||
.@"adjust-box-thickness" = config.@"adjust-box-thickness",
|
.@"adjust-box-thickness" = config.@"adjust-box-thickness",
|
||||||
.@"freetype-load-flags" = if (font.face.FreetypeLoadFlags != void) config.@"freetype-load-flags" else {},
|
.@"freetype-load-flags" = if (font.face.FreetypeLoadFlags != void) config.@"freetype-load-flags" else {},
|
||||||
|
|
||||||
@ -613,6 +615,7 @@ pub const Key = struct {
|
|||||||
if (config.@"adjust-overline-position") |m| try set.put(alloc, .overline_position, m);
|
if (config.@"adjust-overline-position") |m| try set.put(alloc, .overline_position, m);
|
||||||
if (config.@"adjust-overline-thickness") |m| try set.put(alloc, .overline_thickness, m);
|
if (config.@"adjust-overline-thickness") |m| try set.put(alloc, .overline_thickness, m);
|
||||||
if (config.@"adjust-cursor-thickness") |m| try set.put(alloc, .cursor_thickness, m);
|
if (config.@"adjust-cursor-thickness") |m| try set.put(alloc, .cursor_thickness, m);
|
||||||
|
if (config.@"adjust-cursor-height") |m| try set.put(alloc, .cursor_height, m);
|
||||||
if (config.@"adjust-box-thickness") |m| try set.put(alloc, .box_thickness, m);
|
if (config.@"adjust-box-thickness") |m| try set.put(alloc, .box_thickness, m);
|
||||||
break :set set;
|
break :set set;
|
||||||
};
|
};
|
||||||
|
@ -32,10 +32,12 @@ box_thickness: u32,
|
|||||||
/// because it is not determined by fonts but rather by user configuration.
|
/// because it is not determined by fonts but rather by user configuration.
|
||||||
cursor_thickness: u32 = 1,
|
cursor_thickness: u32 = 1,
|
||||||
|
|
||||||
/// Original cell width and height. These are used to render the cursor
|
/// The height in pixels of the cursor sprite.
|
||||||
/// in the original cell size after modification.
|
cursor_height: u32,
|
||||||
|
|
||||||
|
/// Original cell width in pixels. This is used to keep
|
||||||
|
/// glyphs centered if the cell width is adjusted wider.
|
||||||
original_cell_width: ?u32 = null,
|
original_cell_width: ?u32 = null,
|
||||||
original_cell_height: ?u32 = null,
|
|
||||||
|
|
||||||
/// Minimum acceptable values for some fields to prevent modifiers
|
/// Minimum acceptable values for some fields to prevent modifiers
|
||||||
/// from being able to, for example, cause 0-thickness underlines.
|
/// from being able to, for example, cause 0-thickness underlines.
|
||||||
@ -47,6 +49,7 @@ const Minimums = struct {
|
|||||||
const overline_thickness = 1;
|
const overline_thickness = 1;
|
||||||
const box_thickness = 1;
|
const box_thickness = 1;
|
||||||
const cursor_thickness = 1;
|
const cursor_thickness = 1;
|
||||||
|
const cursor_height = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
const CalcOpts = struct {
|
const CalcOpts = struct {
|
||||||
@ -167,6 +170,7 @@ pub fn calc(opts: CalcOpts) Metrics {
|
|||||||
.overline_position = 0,
|
.overline_position = 0,
|
||||||
.overline_thickness = @intFromFloat(underline_thickness),
|
.overline_thickness = @intFromFloat(underline_thickness),
|
||||||
.box_thickness = @intFromFloat(underline_thickness),
|
.box_thickness = @intFromFloat(underline_thickness),
|
||||||
|
.cursor_height = @intFromFloat(cell_height),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure all metrics are within their allowable range.
|
// Ensure all metrics are within their allowable range.
|
||||||
@ -192,10 +196,9 @@ pub fn apply(self: *Metrics, mods: ModifierSet) void {
|
|||||||
const new = @max(entry.value_ptr.apply(original), 1);
|
const new = @max(entry.value_ptr.apply(original), 1);
|
||||||
if (new == original) continue;
|
if (new == original) continue;
|
||||||
|
|
||||||
// Preserve the original cell width and height if not set.
|
// Preserve the original cell width if not set.
|
||||||
if (self.original_cell_width == null) {
|
if (self.original_cell_width == null) {
|
||||||
self.original_cell_width = self.cell_width;
|
self.original_cell_width = self.cell_width;
|
||||||
self.original_cell_height = self.cell_height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the new value
|
// Set the new value
|
||||||
@ -410,6 +413,7 @@ fn init() Metrics {
|
|||||||
.overline_position = 0,
|
.overline_position = 0,
|
||||||
.overline_thickness = 0,
|
.overline_thickness = 0,
|
||||||
.box_thickness = 0,
|
.box_thickness = 0,
|
||||||
|
.cursor_height = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,7 +449,7 @@ test "Metrics: adjust cell height smaller" {
|
|||||||
try testing.expectEqual(@as(u32, 25), m.cell_baseline);
|
try testing.expectEqual(@as(u32, 25), m.cell_baseline);
|
||||||
try testing.expectEqual(@as(u32, 30), m.underline_position);
|
try testing.expectEqual(@as(u32, 30), m.underline_position);
|
||||||
try testing.expectEqual(@as(u32, 5), m.strikethrough_position);
|
try testing.expectEqual(@as(u32, 5), m.strikethrough_position);
|
||||||
try testing.expectEqual(@as(u32, 100), m.original_cell_height.?);
|
try testing.expectEqual(@as(u32, 100), m.cursor_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Metrics: adjust cell height larger" {
|
test "Metrics: adjust cell height larger" {
|
||||||
@ -466,7 +470,7 @@ test "Metrics: adjust cell height larger" {
|
|||||||
try testing.expectEqual(@as(u32, 100), m.cell_baseline);
|
try testing.expectEqual(@as(u32, 100), m.cell_baseline);
|
||||||
try testing.expectEqual(@as(u32, 105), m.underline_position);
|
try testing.expectEqual(@as(u32, 105), m.underline_position);
|
||||||
try testing.expectEqual(@as(u32, 80), m.strikethrough_position);
|
try testing.expectEqual(@as(u32, 80), m.strikethrough_position);
|
||||||
try testing.expectEqual(@as(u32, 100), m.original_cell_height.?);
|
try testing.expectEqual(@as(u32, 100), m.cursor_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Modifier: parse absolute" {
|
test "Modifier: parse absolute" {
|
||||||
|
@ -126,29 +126,20 @@ pub fn renderGlyph(
|
|||||||
},
|
},
|
||||||
|
|
||||||
.cursor => cursor: {
|
.cursor => cursor: {
|
||||||
// Cursors should be drawn with the original cell height if
|
|
||||||
// it has been adjusted larger, so they don't get stretched.
|
|
||||||
const height, const dy = adjust: {
|
|
||||||
const h = metrics.cell_height;
|
|
||||||
if (metrics.original_cell_height) |original| {
|
|
||||||
if (h > original) {
|
|
||||||
break :adjust .{ original, (h - original) / 2 };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break :adjust .{ h, 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
var g = try cursor.renderGlyph(
|
var g = try cursor.renderGlyph(
|
||||||
alloc,
|
alloc,
|
||||||
atlas,
|
atlas,
|
||||||
@enumFromInt(cp),
|
@enumFromInt(cp),
|
||||||
width,
|
width,
|
||||||
height,
|
metrics.cursor_height,
|
||||||
metrics.cursor_thickness,
|
metrics.cursor_thickness,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Keep the cursor centered in the cell if it's shorter.
|
// Cursors are drawn at their specified height
|
||||||
g.offset_y += @intCast(dy);
|
// and are centered vertically within the cell.
|
||||||
|
const cursor_height: i32 = @intCast(metrics.cursor_height);
|
||||||
|
const cell_height: i32 = @intCast(metrics.cell_height);
|
||||||
|
g.offset_y += @divTrunc(cell_height - cursor_height, 2);
|
||||||
|
|
||||||
break :cursor g;
|
break :cursor g;
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user