mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
feat(font): Non-integer point sizes
Allows for high dpi displays to get odd numbered pixel sizes, for example, 13.5pt @ 2px/pt for 27px font. This implementation performs all the sizing calculations with f32, rounding to the nearest pixel size when it comes to rendering. In the future this can be enhanced by adding fractional scaling to support fractional pixel sizes.
This commit is contained in:
@ -194,7 +194,7 @@ const DerivedConfig = struct {
|
||||
arena: ArenaAllocator,
|
||||
|
||||
/// For docs for these, see the associated config they are derived from.
|
||||
original_font_size: u8,
|
||||
original_font_size: f32,
|
||||
keybind: configpkg.Keybinds,
|
||||
clipboard_read: configpkg.ClipboardAccess,
|
||||
clipboard_write: configpkg.ClipboardAccess,
|
||||
@ -321,8 +321,8 @@ pub fn init(
|
||||
// The font size we desire along with the DPI determined for the surface
|
||||
const font_size: font.face.DesiredSize = .{
|
||||
.points = config.@"font-size",
|
||||
.xdpi = @intFromFloat(x_dpi),
|
||||
.ydpi = @intFromFloat(y_dpi),
|
||||
.xdpi = x_dpi,
|
||||
.ydpi = y_dpi,
|
||||
};
|
||||
|
||||
// Setup our font group. This will reuse an existing font group if
|
||||
@ -1703,8 +1703,8 @@ pub fn contentScaleCallback(self: *Surface, content_scale: apprt.ContentScale) !
|
||||
// Update our font size which is dependent on the DPI
|
||||
const size = size: {
|
||||
var size = self.font_size;
|
||||
size.xdpi = @intFromFloat(x_dpi);
|
||||
size.ydpi = @intFromFloat(y_dpi);
|
||||
size.xdpi = x_dpi;
|
||||
size.ydpi = y_dpi;
|
||||
break :size size;
|
||||
};
|
||||
|
||||
@ -3011,7 +3011,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
||||
log.debug("increase font size={}", .{delta});
|
||||
|
||||
var size = self.font_size;
|
||||
size.points +|= delta;
|
||||
size.points = size.points + delta;
|
||||
try self.setFontSize(size);
|
||||
},
|
||||
|
||||
@ -3019,7 +3019,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
||||
log.debug("decrease font size={}", .{delta});
|
||||
|
||||
var size = self.font_size;
|
||||
size.points = @max(1, size.points -| delta);
|
||||
size.points = @max(1, size.points - delta);
|
||||
try self.setFontSize(size);
|
||||
},
|
||||
|
||||
|
@ -250,8 +250,10 @@ fn parseIntoField(
|
||||
0,
|
||||
) catch return error.InvalidValue,
|
||||
|
||||
f64 => std.fmt.parseFloat(
|
||||
f64,
|
||||
f32,
|
||||
f64,
|
||||
=> |Float| std.fmt.parseFloat(
|
||||
Float,
|
||||
value orelse return error.ValueRequired,
|
||||
) catch return error.InvalidValue,
|
||||
|
||||
|
@ -99,8 +99,12 @@ const c = @cImport({
|
||||
/// separate repetitive entries in your config).
|
||||
@"font-feature": RepeatableString = .{},
|
||||
|
||||
/// Font size in points
|
||||
@"font-size": u8 = switch (builtin.os.tag) {
|
||||
/// Font size in points. This value can be a non-integer and the nearest integer
|
||||
/// pixel size will be selected. If you have a high dpi display where 1pt = 2px
|
||||
/// then you can get an odd numbered pixel size by specifying a half point.
|
||||
///
|
||||
/// For example, 13.5pt @ 2px/pt = 27px
|
||||
@"font-size": f32 = switch (builtin.os.tag) {
|
||||
// On macOS we default a little bigger since this tends to look better. This
|
||||
// is purely subjective but this is easy to modify.
|
||||
.macos => 13,
|
||||
|
@ -575,7 +575,9 @@ pub const Key = struct {
|
||||
/// Hash the key with the given hasher.
|
||||
pub fn hash(self: Key, hasher: anytype) void {
|
||||
const autoHash = std.hash.autoHash;
|
||||
autoHash(hasher, self.font_size);
|
||||
autoHash(hasher, @as(u32, @bitCast(self.font_size.points)));
|
||||
autoHash(hasher, @as(u32, @bitCast(self.font_size.xdpi)));
|
||||
autoHash(hasher, @as(u32, @bitCast(self.font_size.ydpi)));
|
||||
autoHash(hasher, self.descriptors.len);
|
||||
for (self.descriptors) |d| d.hash(hasher);
|
||||
self.codepoint_map.hash(hasher);
|
||||
|
@ -49,7 +49,7 @@ pub const Descriptor = struct {
|
||||
/// Font size in points that the font should support. For conversion
|
||||
/// to pixels, we will use 72 DPI for Mac and 96 DPI for everything else.
|
||||
/// (If pixel conversion is necessary, i.e. emoji fonts)
|
||||
size: u16 = 0,
|
||||
size: f32 = 0,
|
||||
|
||||
/// True if we want to search specifically for a font that supports
|
||||
/// specific styles.
|
||||
@ -69,7 +69,7 @@ pub const Descriptor = struct {
|
||||
autoHashStrat(hasher, self.family, .Deep);
|
||||
autoHashStrat(hasher, self.style, .Deep);
|
||||
autoHash(hasher, self.codepoint);
|
||||
autoHash(hasher, self.size);
|
||||
autoHash(hasher, @as(u32, @bitCast(self.size)));
|
||||
autoHash(hasher, self.bold);
|
||||
autoHash(hasher, self.italic);
|
||||
autoHash(hasher, self.monospace);
|
||||
@ -125,7 +125,7 @@ pub const Descriptor = struct {
|
||||
}
|
||||
if (self.size > 0) assert(pat.add(
|
||||
.size,
|
||||
.{ .integer = self.size },
|
||||
.{ .integer = @round(self.size) },
|
||||
false,
|
||||
));
|
||||
if (self.bold) assert(pat.add(
|
||||
@ -183,7 +183,7 @@ pub const Descriptor = struct {
|
||||
|
||||
// Set our size attribute if set
|
||||
if (self.size > 0) {
|
||||
const size32 = @as(i32, @intCast(self.size));
|
||||
const size32: i32 = @intFromFloat(@round(self.size));
|
||||
const size = try macos.foundation.Number.create(
|
||||
.sint32,
|
||||
&size32,
|
||||
|
@ -35,17 +35,16 @@ pub const Options = struct {
|
||||
/// The desired size for loading a font.
|
||||
pub const DesiredSize = struct {
|
||||
// Desired size in points
|
||||
points: u8,
|
||||
points: f32,
|
||||
|
||||
// The DPI of the screen so we can convert points to pixels.
|
||||
xdpi: u16 = default_dpi,
|
||||
ydpi: u16 = default_dpi,
|
||||
xdpi: f32 = default_dpi,
|
||||
ydpi: f32 = default_dpi,
|
||||
|
||||
// Converts points to pixels
|
||||
pub fn pixels(self: DesiredSize) u16 {
|
||||
// 1 point = 1/72 inch
|
||||
const points_u16: u16 = @intCast(self.points);
|
||||
return (points_u16 * self.ydpi) / 72;
|
||||
return @intFromFloat(@round((self.points * self.ydpi) / 72));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -158,8 +158,8 @@ pub const Action = union(enum) {
|
||||
paste_from_selection: void,
|
||||
|
||||
/// Increase/decrease the font size by a certain amount.
|
||||
increase_font_size: u8,
|
||||
decrease_font_size: u8,
|
||||
increase_font_size: f32,
|
||||
decrease_font_size: f32,
|
||||
|
||||
/// Reset the font size to the original configured size.
|
||||
reset_font_size: void,
|
||||
|
Reference in New Issue
Block a user