Skip to content

Commit

Permalink
font(coretext): add config to adjust strength of font-thicken. (#4531)
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
mitchellh authored Jan 5, 2025
2 parents 68624e6 + 25a1124 commit 62dd468
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 6 deletions.
14 changes: 12 additions & 2 deletions src/config/Config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/font/face.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
9 changes: 5 additions & 4 deletions src/font/face/coretext.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 = .{
Expand All @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/Metal.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,

Expand Down Expand Up @@ -2837,6 +2839,7 @@ fn addGlyph(
.{
.grid_metrics = self.grid_metrics,
.thicken = self.config.font_thicken,
.thicken_strength = self.config.font_thicken_strength,
},
);

Expand Down
3 changes: 3 additions & 0 deletions src/renderer/OpenGL.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,

Expand Down Expand Up @@ -2093,6 +2095,7 @@ fn addGlyph(
.{
.grid_metrics = self.grid_metrics,
.thicken = self.config.font_thicken,
.thicken_strength = self.config.font_thicken_strength,
},
);

Expand Down

0 comments on commit 62dd468

Please sign in to comment.