mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
Merge pull request #982 from mitchellh/font-metrics
font: faces use primary grid metrics to better line up glyphs
This commit is contained in:
@ -71,10 +71,11 @@ pub const Variation = struct {
|
|||||||
|
|
||||||
/// Additional options for rendering glyphs.
|
/// Additional options for rendering glyphs.
|
||||||
pub const RenderOptions = struct {
|
pub const RenderOptions = struct {
|
||||||
/// The maximum height of the glyph. If this is set, then any glyph
|
/// The metrics that are defining the grid layout. These are usually
|
||||||
/// larger than this height will be shrunk to this height. The scaling
|
/// the metrics of the primary font face. The grid metrics are used
|
||||||
/// is typically naive, but ultimately up to the rasterizer.
|
/// by the font face to better layout the glyph in situations where
|
||||||
max_height: ?u16 = null,
|
/// the font is not exactly the same size as the grid.
|
||||||
|
grid_metrics: ?Metrics = null,
|
||||||
|
|
||||||
/// The number of grid cells this glyph will take up. This can be used
|
/// The number of grid cells this glyph will take up. This can be used
|
||||||
/// optionally by the rasterizer to better layout the glyph.
|
/// optionally by the rasterizer to better layout the glyph.
|
||||||
|
@ -386,7 +386,9 @@ pub const Face = struct {
|
|||||||
const offset_y: i32 = offset_y: {
|
const offset_y: i32 = offset_y: {
|
||||||
// Our Y coordinate in 3D is (0, 0) bottom left, +y is UP.
|
// Our Y coordinate in 3D is (0, 0) bottom left, +y is UP.
|
||||||
// We need to calculate our baseline from the bottom of a cell.
|
// We need to calculate our baseline from the bottom of a cell.
|
||||||
const baseline_from_bottom: f64 = @floatFromInt(self.metrics.cell_baseline);
|
//const baseline_from_bottom: f64 = @floatFromInt(self.metrics.cell_baseline);
|
||||||
|
const metrics = opts.grid_metrics orelse self.metrics;
|
||||||
|
const baseline_from_bottom: f64 = @floatFromInt(metrics.cell_baseline);
|
||||||
|
|
||||||
// Next we offset our baseline by the bearing in the font. We
|
// Next we offset our baseline by the bearing in the font. We
|
||||||
// ADD here because CoreText y is UP.
|
// ADD here because CoreText y is UP.
|
||||||
|
@ -226,6 +226,8 @@ pub const Face = struct {
|
|||||||
glyph_index: u32,
|
glyph_index: u32,
|
||||||
opts: font.face.RenderOptions,
|
opts: font.face.RenderOptions,
|
||||||
) !Glyph {
|
) !Glyph {
|
||||||
|
const metrics = opts.grid_metrics orelse self.metrics;
|
||||||
|
|
||||||
// If our glyph has color, we want to render the color
|
// If our glyph has color, we want to render the color
|
||||||
try self.face.loadGlyph(glyph_index, .{
|
try self.face.loadGlyph(glyph_index, .{
|
||||||
.render = true,
|
.render = true,
|
||||||
@ -288,7 +290,7 @@ pub const Face = struct {
|
|||||||
// and copy the atlas.
|
// and copy the atlas.
|
||||||
const bitmap_original = bitmap_converted orelse bitmap_ft;
|
const bitmap_original = bitmap_converted orelse bitmap_ft;
|
||||||
const bitmap_resized: ?freetype.c.struct_FT_Bitmap_ = resized: {
|
const bitmap_resized: ?freetype.c.struct_FT_Bitmap_ = resized: {
|
||||||
const max = opts.max_height orelse break :resized null;
|
const max = metrics.cell_height;
|
||||||
const bm = bitmap_original;
|
const bm = bitmap_original;
|
||||||
if (bm.rows <= max) break :resized null;
|
if (bm.rows <= max) break :resized null;
|
||||||
|
|
||||||
@ -425,7 +427,7 @@ pub const Face = struct {
|
|||||||
// baseline calculation. The baseline calculation is so that everything
|
// baseline calculation. The baseline calculation is so that everything
|
||||||
// is properly centered when we render it out into a monospace grid.
|
// is properly centered when we render it out into a monospace grid.
|
||||||
// Note: we add here because our X/Y is actually reversed, adding goes UP.
|
// Note: we add here because our X/Y is actually reversed, adding goes UP.
|
||||||
break :offset_y glyph_metrics.bitmap_top + @as(c_int, @intCast(self.metrics.cell_baseline));
|
break :offset_y glyph_metrics.bitmap_top + @as(c_int, @intCast(metrics.cell_baseline));
|
||||||
};
|
};
|
||||||
|
|
||||||
// log.warn("renderGlyph width={} height={} offset_x={} offset_y={} glyph_metrics={}", .{
|
// log.warn("renderGlyph width={} height={} offset_x={} offset_y={} glyph_metrics={}", .{
|
||||||
@ -662,7 +664,15 @@ test "color emoji" {
|
|||||||
// resize
|
// resize
|
||||||
{
|
{
|
||||||
const glyph = try ft_font.renderGlyph(alloc, &atlas, ft_font.glyphIndex('🥸').?, .{
|
const glyph = try ft_font.renderGlyph(alloc, &atlas, ft_font.glyphIndex('🥸').?, .{
|
||||||
.max_height = 24,
|
.grid_metrics = .{
|
||||||
|
.cell_width = 10,
|
||||||
|
.cell_height = 24,
|
||||||
|
.cell_baseline = 0,
|
||||||
|
.underline_position = 0,
|
||||||
|
.underline_thickness = 0,
|
||||||
|
.strikethrough_position = 0,
|
||||||
|
.strikethrough_thickness = 0,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
try testing.expectEqual(@as(u32, 24), glyph.height);
|
try testing.expectEqual(@as(u32, 24), glyph.height);
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ config: DerivedConfig,
|
|||||||
/// The mailbox for communicating with the window.
|
/// The mailbox for communicating with the window.
|
||||||
surface_mailbox: apprt.surface.Mailbox,
|
surface_mailbox: apprt.surface.Mailbox,
|
||||||
|
|
||||||
/// Current cell dimensions for this grid.
|
/// Current font metrics defining our grid.
|
||||||
cell_size: renderer.CellSize,
|
grid_metrics: font.face.Metrics,
|
||||||
|
|
||||||
/// Current screen size dimensions for this grid. This is set on the first
|
/// Current screen size dimensions for this grid. This is set on the first
|
||||||
/// resize event, and is not immediately available.
|
/// resize event, and is not immediately available.
|
||||||
@ -359,7 +359,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
|||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.config = options.config,
|
.config = options.config,
|
||||||
.surface_mailbox = options.surface_mailbox,
|
.surface_mailbox = options.surface_mailbox,
|
||||||
.cell_size = .{ .width = metrics.cell_width, .height = metrics.cell_height },
|
.grid_metrics = metrics,
|
||||||
.screen_size = null,
|
.screen_size = null,
|
||||||
.padding = options.padding,
|
.padding = options.padding,
|
||||||
.focused = true,
|
.focused = true,
|
||||||
@ -497,7 +497,10 @@ fn gridSize(self: *Metal) ?renderer.GridSize {
|
|||||||
const screen_size = self.screen_size orelse return null;
|
const screen_size = self.screen_size orelse return null;
|
||||||
return renderer.GridSize.init(
|
return renderer.GridSize.init(
|
||||||
screen_size.subPadding(self.padding.explicit),
|
screen_size.subPadding(self.padding.explicit),
|
||||||
self.cell_size,
|
.{
|
||||||
|
.width = self.grid_metrics.cell_width,
|
||||||
|
.height = self.grid_metrics.cell_height,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,14 +526,13 @@ pub fn setFontSize(self: *Metal, size: font.face.DesiredSize) !void {
|
|||||||
const face = try self.font_group.group.faceFromIndex(index);
|
const face = try self.font_group.group.faceFromIndex(index);
|
||||||
break :metrics face.metrics;
|
break :metrics face.metrics;
|
||||||
};
|
};
|
||||||
const new_cell_size = .{ .width = metrics.cell_width, .height = metrics.cell_height };
|
|
||||||
|
|
||||||
// Update our uniforms
|
// Update our uniforms
|
||||||
self.uniforms = .{
|
self.uniforms = .{
|
||||||
.projection_matrix = self.uniforms.projection_matrix,
|
.projection_matrix = self.uniforms.projection_matrix,
|
||||||
.cell_size = .{
|
.cell_size = .{
|
||||||
@floatFromInt(new_cell_size.width),
|
@floatFromInt(metrics.cell_width),
|
||||||
@floatFromInt(new_cell_size.height),
|
@floatFromInt(metrics.cell_height),
|
||||||
},
|
},
|
||||||
.strikethrough_position = @floatFromInt(metrics.strikethrough_position),
|
.strikethrough_position = @floatFromInt(metrics.strikethrough_position),
|
||||||
.strikethrough_thickness = @floatFromInt(metrics.strikethrough_thickness),
|
.strikethrough_thickness = @floatFromInt(metrics.strikethrough_thickness),
|
||||||
@ -539,20 +541,23 @@ pub fn setFontSize(self: *Metal, size: font.face.DesiredSize) !void {
|
|||||||
|
|
||||||
// Recalculate our cell size. If it is the same as before, then we do
|
// Recalculate our cell size. If it is the same as before, then we do
|
||||||
// nothing since the grid size couldn't have possibly changed.
|
// nothing since the grid size couldn't have possibly changed.
|
||||||
if (std.meta.eql(self.cell_size, new_cell_size)) return;
|
if (std.meta.eql(self.grid_metrics, metrics)) return;
|
||||||
self.cell_size = new_cell_size;
|
self.grid_metrics = metrics;
|
||||||
|
|
||||||
// Set the sprite font up
|
// Set the sprite font up
|
||||||
self.font_group.group.sprite = font.sprite.Face{
|
self.font_group.group.sprite = font.sprite.Face{
|
||||||
.width = self.cell_size.width,
|
.width = metrics.cell_width,
|
||||||
.height = self.cell_size.height,
|
.height = metrics.cell_height,
|
||||||
.thickness = metrics.underline_thickness * @as(u32, if (self.config.font_thicken) 2 else 1),
|
.thickness = metrics.underline_thickness * @as(u32, if (self.config.font_thicken) 2 else 1),
|
||||||
.underline_position = metrics.underline_position,
|
.underline_position = metrics.underline_position,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Notify the window that the cell size changed.
|
// Notify the window that the cell size changed.
|
||||||
_ = self.surface_mailbox.push(.{
|
_ = self.surface_mailbox.push(.{
|
||||||
.cell_size = new_cell_size,
|
.cell_size = .{
|
||||||
|
.width = metrics.cell_width,
|
||||||
|
.height = metrics.cell_height,
|
||||||
|
},
|
||||||
}, .{ .forever = {} });
|
}, .{ .forever = {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1140,7 +1145,7 @@ fn prepKittyGraphics(
|
|||||||
// so that we render (0, 0) with some offset for the texture.
|
// so that we render (0, 0) with some offset for the texture.
|
||||||
const offset_y: u32 = if (rect.top_left.y < t.screen.viewport) offset_y: {
|
const offset_y: u32 = if (rect.top_left.y < t.screen.viewport) offset_y: {
|
||||||
const offset_cells = t.screen.viewport - rect.top_left.y;
|
const offset_cells = t.screen.viewport - rect.top_left.y;
|
||||||
const offset_pixels = offset_cells * self.cell_size.height;
|
const offset_pixels = offset_cells * self.grid_metrics.cell_height;
|
||||||
break :offset_y @intCast(offset_pixels);
|
break :offset_y @intCast(offset_pixels);
|
||||||
} else 0;
|
} else 0;
|
||||||
|
|
||||||
@ -1181,8 +1186,8 @@ fn prepKittyGraphics(
|
|||||||
image.height -| offset_y;
|
image.height -| offset_y;
|
||||||
|
|
||||||
// Calculate the width/height of our image.
|
// Calculate the width/height of our image.
|
||||||
const dest_width = if (p.columns > 0) p.columns * self.cell_size.width else source_width;
|
const dest_width = if (p.columns > 0) p.columns * self.grid_metrics.cell_width else source_width;
|
||||||
const dest_height = if (p.rows > 0) p.rows * self.cell_size.height else source_height;
|
const dest_height = if (p.rows > 0) p.rows * self.grid_metrics.cell_height else source_height;
|
||||||
|
|
||||||
// Accumulate the placement
|
// Accumulate the placement
|
||||||
if (image.width > 0 and image.height > 0) {
|
if (image.width > 0 and image.height > 0) {
|
||||||
@ -1286,7 +1291,14 @@ pub fn setScreenSize(
|
|||||||
// the leftover amounts on the right/bottom that don't fit a full grid cell
|
// the leftover amounts on the right/bottom that don't fit a full grid cell
|
||||||
// and we split them equal across all boundaries.
|
// and we split them equal across all boundaries.
|
||||||
const padding = if (self.padding.balance)
|
const padding = if (self.padding.balance)
|
||||||
renderer.Padding.balanced(dim, grid_size, self.cell_size)
|
renderer.Padding.balanced(
|
||||||
|
dim,
|
||||||
|
grid_size,
|
||||||
|
.{
|
||||||
|
.width = self.grid_metrics.cell_width,
|
||||||
|
.height = self.grid_metrics.cell_height,
|
||||||
|
},
|
||||||
|
)
|
||||||
else
|
else
|
||||||
self.padding.explicit;
|
self.padding.explicit;
|
||||||
const padded_dim = dim.subPadding(padding);
|
const padded_dim = dim.subPadding(padding);
|
||||||
@ -1307,8 +1319,8 @@ pub fn setScreenSize(
|
|||||||
-1 * @as(f32, @floatFromInt(padding.top)),
|
-1 * @as(f32, @floatFromInt(padding.top)),
|
||||||
),
|
),
|
||||||
.cell_size = .{
|
.cell_size = .{
|
||||||
@floatFromInt(self.cell_size.width),
|
@floatFromInt(self.grid_metrics.cell_width),
|
||||||
@floatFromInt(self.cell_size.height),
|
@floatFromInt(self.grid_metrics.cell_height),
|
||||||
},
|
},
|
||||||
.strikethrough_position = old.strikethrough_position,
|
.strikethrough_position = old.strikethrough_position,
|
||||||
.strikethrough_thickness = old.strikethrough_thickness,
|
.strikethrough_thickness = old.strikethrough_thickness,
|
||||||
@ -1366,7 +1378,7 @@ pub fn setScreenSize(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("screen size screen={} grid={}, cell={}", .{ dim, grid_size, self.cell_size });
|
log.debug("screen size screen={} grid={}, cell_width={} cell_height={}", .{ dim, grid_size, self.grid_metrics.cell_width, self.grid_metrics.cell_height });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sync all the CPU cells with the GPU state (but still on the CPU here).
|
/// Sync all the CPU cells with the GPU state (but still on the CPU here).
|
||||||
@ -1728,7 +1740,7 @@ pub fn updateCell(
|
|||||||
shaper_run.font_index,
|
shaper_run.font_index,
|
||||||
shaper_cell.glyph_index,
|
shaper_cell.glyph_index,
|
||||||
.{
|
.{
|
||||||
.max_height = @intCast(self.cell_size.height),
|
.grid_metrics = self.grid_metrics,
|
||||||
.thicken = self.config.font_thicken,
|
.thicken = self.config.font_thicken,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -1766,7 +1778,10 @@ pub fn updateCell(
|
|||||||
self.alloc,
|
self.alloc,
|
||||||
font.sprite_index,
|
font.sprite_index,
|
||||||
@intFromEnum(sprite),
|
@intFromEnum(sprite),
|
||||||
.{ .cell_width = if (cell.attrs.wide) 2 else 1 },
|
.{
|
||||||
|
.cell_width = if (cell.attrs.wide) 2 else 1,
|
||||||
|
.grid_metrics = self.grid_metrics,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const color = if (cell.attrs.underline_color) cell.underline_fg else colors.fg;
|
const color = if (cell.attrs.underline_color) cell.underline_fg else colors.fg;
|
||||||
@ -1839,7 +1854,10 @@ fn addCursor(
|
|||||||
self.alloc,
|
self.alloc,
|
||||||
font.sprite_index,
|
font.sprite_index,
|
||||||
@intFromEnum(sprite),
|
@intFromEnum(sprite),
|
||||||
.{ .cell_width = if (wide) 2 else 1 },
|
.{
|
||||||
|
.cell_width = if (wide) 2 else 1,
|
||||||
|
.grid_metrics = self.grid_metrics,
|
||||||
|
},
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
log.warn("error rendering cursor glyph err={}", .{err});
|
log.warn("error rendering cursor glyph err={}", .{err});
|
||||||
return null;
|
return null;
|
||||||
@ -1894,7 +1912,7 @@ fn addPreeditCell(
|
|||||||
self.alloc,
|
self.alloc,
|
||||||
font_index,
|
font_index,
|
||||||
glyph_index,
|
glyph_index,
|
||||||
.{},
|
.{ .grid_metrics = self.grid_metrics },
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
log.warn("error rendering preedit glyph err={}", .{err});
|
log.warn("error rendering preedit glyph err={}", .{err});
|
||||||
return;
|
return;
|
||||||
|
@ -47,8 +47,8 @@ alloc: std.mem.Allocator,
|
|||||||
/// The configuration we need derived from the main config.
|
/// The configuration we need derived from the main config.
|
||||||
config: DerivedConfig,
|
config: DerivedConfig,
|
||||||
|
|
||||||
/// Current cell dimensions for this grid.
|
/// Current font metrics defining our grid.
|
||||||
cell_size: renderer.CellSize,
|
grid_metrics: font.face.Metrics,
|
||||||
|
|
||||||
/// Current screen size dimensions for this grid. This is set on the first
|
/// Current screen size dimensions for this grid. This is set on the first
|
||||||
/// resize event, and is not immediately available.
|
/// resize event, and is not immediately available.
|
||||||
@ -128,7 +128,14 @@ const SetScreenSize = struct {
|
|||||||
|
|
||||||
// Apply our padding
|
// Apply our padding
|
||||||
const padding = if (r.padding.balance)
|
const padding = if (r.padding.balance)
|
||||||
renderer.Padding.balanced(self.size, r.gridSize(self.size), r.cell_size)
|
renderer.Padding.balanced(
|
||||||
|
self.size,
|
||||||
|
r.gridSize(self.size),
|
||||||
|
.{
|
||||||
|
.width = r.grid_metrics.cell_width,
|
||||||
|
.height = r.grid_metrics.cell_height,
|
||||||
|
},
|
||||||
|
)
|
||||||
else
|
else
|
||||||
r.padding.explicit;
|
r.padding.explicit;
|
||||||
const padded_size = self.size.subPadding(padding);
|
const padded_size = self.size.subPadding(padding);
|
||||||
@ -137,7 +144,10 @@ const SetScreenSize = struct {
|
|||||||
padded_size,
|
padded_size,
|
||||||
self.size,
|
self.size,
|
||||||
r.gridSize(self.size),
|
r.gridSize(self.size),
|
||||||
r.cell_size,
|
renderer.CellSize{
|
||||||
|
.width = r.grid_metrics.cell_width,
|
||||||
|
.height = r.grid_metrics.cell_height,
|
||||||
|
},
|
||||||
r.padding.explicit,
|
r.padding.explicit,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -340,7 +350,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
|
|||||||
.config = options.config,
|
.config = options.config,
|
||||||
.cells_bg = .{},
|
.cells_bg = .{},
|
||||||
.cells = .{},
|
.cells = .{},
|
||||||
.cell_size = .{ .width = metrics.cell_width, .height = metrics.cell_height },
|
.grid_metrics = metrics,
|
||||||
.screen_size = null,
|
.screen_size = null,
|
||||||
.gl_state = gl_state,
|
.gl_state = gl_state,
|
||||||
.font_group = options.font_group,
|
.font_group = options.font_group,
|
||||||
@ -576,13 +586,15 @@ pub fn setFontSize(self: *OpenGL, size: font.face.DesiredSize) !void {
|
|||||||
|
|
||||||
// Recalculate our cell size. If it is the same as before, then we do
|
// Recalculate our cell size. If it is the same as before, then we do
|
||||||
// nothing since the grid size couldn't have possibly changed.
|
// nothing since the grid size couldn't have possibly changed.
|
||||||
const new_cell_size = .{ .width = metrics.cell_width, .height = metrics.cell_height };
|
if (std.meta.eql(self.grid_metrics, metrics)) return;
|
||||||
if (std.meta.eql(self.cell_size, new_cell_size)) return;
|
self.grid_metrics = metrics;
|
||||||
self.cell_size = new_cell_size;
|
|
||||||
|
|
||||||
// Notify the window that the cell size changed.
|
// Notify the window that the cell size changed.
|
||||||
_ = self.surface_mailbox.push(.{
|
_ = self.surface_mailbox.push(.{
|
||||||
.cell_size = new_cell_size,
|
.cell_size = .{
|
||||||
|
.width = metrics.cell_width,
|
||||||
|
.height = metrics.cell_height,
|
||||||
|
},
|
||||||
}, .{ .forever = {} });
|
}, .{ .forever = {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,7 +792,7 @@ fn prepKittyGraphics(
|
|||||||
// so that we render (0, 0) with some offset for the texture.
|
// so that we render (0, 0) with some offset for the texture.
|
||||||
const offset_y: u32 = if (rect.top_left.y < t.screen.viewport) offset_y: {
|
const offset_y: u32 = if (rect.top_left.y < t.screen.viewport) offset_y: {
|
||||||
const offset_cells = t.screen.viewport - rect.top_left.y;
|
const offset_cells = t.screen.viewport - rect.top_left.y;
|
||||||
const offset_pixels = offset_cells * self.cell_size.height;
|
const offset_pixels = offset_cells * self.grid_metrics.cell_height;
|
||||||
break :offset_y @intCast(offset_pixels);
|
break :offset_y @intCast(offset_pixels);
|
||||||
} else 0;
|
} else 0;
|
||||||
|
|
||||||
@ -821,8 +833,8 @@ fn prepKittyGraphics(
|
|||||||
image.height -| offset_y;
|
image.height -| offset_y;
|
||||||
|
|
||||||
// Calculate the width/height of our image.
|
// Calculate the width/height of our image.
|
||||||
const dest_width = if (p.columns > 0) p.columns * self.cell_size.width else source_width;
|
const dest_width = if (p.columns > 0) p.columns * self.grid_metrics.cell_width else source_width;
|
||||||
const dest_height = if (p.rows > 0) p.rows * self.cell_size.height else source_height;
|
const dest_height = if (p.rows > 0) p.rows * self.grid_metrics.cell_height else source_height;
|
||||||
|
|
||||||
// Accumulate the placement
|
// Accumulate the placement
|
||||||
if (image.width > 0 and image.height > 0) {
|
if (image.width > 0 and image.height > 0) {
|
||||||
@ -1145,7 +1157,7 @@ fn addPreeditCell(
|
|||||||
self.alloc,
|
self.alloc,
|
||||||
font_index,
|
font_index,
|
||||||
glyph_index,
|
glyph_index,
|
||||||
.{},
|
.{ .grid_metrics = self.grid_metrics },
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
log.warn("error rendering preedit glyph err={}", .{err});
|
log.warn("error rendering preedit glyph err={}", .{err});
|
||||||
return;
|
return;
|
||||||
@ -1239,7 +1251,10 @@ fn addCursor(
|
|||||||
self.alloc,
|
self.alloc,
|
||||||
font.sprite_index,
|
font.sprite_index,
|
||||||
@intFromEnum(sprite),
|
@intFromEnum(sprite),
|
||||||
.{ .cell_width = if (wide) 2 else 1 },
|
.{
|
||||||
|
.grid_metrics = self.grid_metrics,
|
||||||
|
.cell_width = if (wide) 2 else 1,
|
||||||
|
},
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
log.warn("error rendering cursor glyph err={}", .{err});
|
log.warn("error rendering cursor glyph err={}", .{err});
|
||||||
return null;
|
return null;
|
||||||
@ -1431,7 +1446,7 @@ pub fn updateCell(
|
|||||||
shaper_run.font_index,
|
shaper_run.font_index,
|
||||||
shaper_cell.glyph_index,
|
shaper_cell.glyph_index,
|
||||||
.{
|
.{
|
||||||
.max_height = @intCast(self.cell_size.height),
|
.grid_metrics = self.grid_metrics,
|
||||||
.thicken = self.config.font_thicken,
|
.thicken = self.config.font_thicken,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -1479,7 +1494,10 @@ pub fn updateCell(
|
|||||||
self.alloc,
|
self.alloc,
|
||||||
font.sprite_index,
|
font.sprite_index,
|
||||||
@intFromEnum(sprite),
|
@intFromEnum(sprite),
|
||||||
.{ .cell_width = if (cell.attrs.wide) 2 else 1 },
|
.{
|
||||||
|
.grid_metrics = self.grid_metrics,
|
||||||
|
.cell_width = if (cell.attrs.wide) 2 else 1,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const color = if (cell.attrs.underline_color) cell.underline_fg else colors.fg;
|
const color = if (cell.attrs.underline_color) cell.underline_fg else colors.fg;
|
||||||
@ -1537,7 +1555,10 @@ pub fn updateCell(
|
|||||||
fn gridSize(self: *const OpenGL, screen_size: renderer.ScreenSize) renderer.GridSize {
|
fn gridSize(self: *const OpenGL, screen_size: renderer.ScreenSize) renderer.GridSize {
|
||||||
return renderer.GridSize.init(
|
return renderer.GridSize.init(
|
||||||
screen_size.subPadding(self.padding.explicit),
|
screen_size.subPadding(self.padding.explicit),
|
||||||
self.cell_size,
|
.{
|
||||||
|
.width = self.grid_metrics.cell_width,
|
||||||
|
.height = self.grid_metrics.cell_height,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1598,7 +1619,10 @@ pub fn setScreenSize(
|
|||||||
log.debug("screen size screen={} grid={} cell={} padding={}", .{
|
log.debug("screen size screen={} grid={} cell={} padding={}", .{
|
||||||
dim,
|
dim,
|
||||||
grid_size,
|
grid_size,
|
||||||
self.cell_size,
|
renderer.CellSize{
|
||||||
|
.width = self.grid_metrics.cell_width,
|
||||||
|
.height = self.grid_metrics.cell_height,
|
||||||
|
},
|
||||||
self.padding.explicit,
|
self.padding.explicit,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user