font(coretext): add config to adjust strength of font-thicken.

This is achieved by rendering to an alpha-only context rather than a
normal single-channel context, and adjusting the brightness at which
coretext thinks it's drawing the glyph, which affects how it applies
font smoothing (which is what `font-thicken` enables).
This commit is contained in:
Qwerasd
2025-01-03 14:19:19 -05:00
parent 7eb35d7275
commit 25a112469c
5 changed files with 32 additions and 6 deletions

View File

@ -234,10 +234,20 @@ const c = @cImport({
/// i.e. new windows, tabs, etc.
@"font-codepoint-map": RepeatableCodepointMap = .{},
/// Draw fonts with a thicker stroke, if supported. This is only supported
/// currently on macOS.
/// Draw fonts with a thicker stroke, if supported.
/// This is currently only supported on macOS.
@"font-thicken": bool = false,
/// Strength of thickening when `font-thicken` is enabled.
///
/// Valid values are integers between `0` and `255`. `0` does not correspond to
/// *no* thickening, rather it corresponds to the lightest available thickening.
///
/// Has no effect when `font-thicken` is set to `false`.
///
/// This is currently only supported on macOS.
@"font-thicken-strength": u8 = 255,
/// All of the configurations behavior adjust various metrics determined by the
/// font. The values can be integers (1, -1, etc.) or a percentage (20%, -15%,
/// etc.). In each case, the values represent the amount to change the original

View File

@ -100,6 +100,15 @@ pub const RenderOptions = struct {
///
/// This only works with CoreText currently.
thicken: bool = false,
/// "Strength" of the thickening, between `0` and `255`.
/// Only has an effect when `thicken` is enabled.
///
/// `0` does not correspond to *no* thickening,
/// just the *lightest* thickening available.
///
/// CoreText only.
thicken_strength: u8 = 255,
};
test {

View File

@ -354,7 +354,7 @@ pub const Face = struct {
.depth = 1,
.space = try macos.graphics.ColorSpace.createDeviceGray(),
.context_opts = @intFromEnum(macos.graphics.BitmapInfo.alpha_mask) &
@intFromEnum(macos.graphics.ImageAlphaInfo.none),
@intFromEnum(macos.graphics.ImageAlphaInfo.only),
} else .{
.color = true,
.depth = 4,
@ -398,7 +398,7 @@ pub const Face = struct {
if (color.color)
context.setRGBFillColor(ctx, 1, 1, 1, 0)
else
context.setGrayFillColor(ctx, 0, 0);
context.setGrayFillColor(ctx, 1, 0);
context.fillRect(ctx, .{
.origin = .{ .x = 0, .y = 0 },
.size = .{
@ -421,8 +421,9 @@ pub const Face = struct {
context.setRGBFillColor(ctx, 1, 1, 1, 1);
context.setRGBStrokeColor(ctx, 1, 1, 1, 1);
} else {
context.setGrayFillColor(ctx, 1, 1);
context.setGrayStrokeColor(ctx, 1, 1);
const strength: f64 = @floatFromInt(opts.thicken_strength);
context.setGrayFillColor(ctx, strength / 255.0, 1);
context.setGrayStrokeColor(ctx, strength / 255.0, 1);
}
// If we are drawing with synthetic bold then use a fill stroke

View File

@ -360,6 +360,7 @@ pub const DerivedConfig = struct {
arena: ArenaAllocator,
font_thicken: bool,
font_thicken_strength: u8,
font_features: std.ArrayListUnmanaged([:0]const u8),
font_styles: font.CodepointResolver.StyleStatus,
cursor_color: ?terminal.color.RGB,
@ -410,6 +411,7 @@ pub const DerivedConfig = struct {
return .{
.background_opacity = @max(0, @min(1, config.@"background-opacity")),
.font_thicken = config.@"font-thicken",
.font_thicken_strength = config.@"font-thicken-strength",
.font_features = font_features.list,
.font_styles = font_styles,
@ -2837,6 +2839,7 @@ fn addGlyph(
.{
.grid_metrics = self.grid_metrics,
.thicken = self.config.font_thicken,
.thicken_strength = self.config.font_thicken_strength,
},
);

View File

@ -272,6 +272,7 @@ pub const DerivedConfig = struct {
arena: ArenaAllocator,
font_thicken: bool,
font_thicken_strength: u8,
font_features: std.ArrayListUnmanaged([:0]const u8),
font_styles: font.CodepointResolver.StyleStatus,
cursor_color: ?terminal.color.RGB,
@ -321,6 +322,7 @@ pub const DerivedConfig = struct {
return .{
.background_opacity = @max(0, @min(1, config.@"background-opacity")),
.font_thicken = config.@"font-thicken",
.font_thicken_strength = config.@"font-thicken-strength",
.font_features = font_features.list,
.font_styles = font_styles,
@ -2093,6 +2095,7 @@ fn addGlyph(
.{
.grid_metrics = self.grid_metrics,
.thicken = self.config.font_thicken,
.thicken_strength = self.config.font_thicken_strength,
},
);