mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
renderer: font size changed event, OpenGL impl
This commit is contained in:
@ -156,22 +156,15 @@ pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL {
|
||||
var shaper = try font.Shaper.init(shape_buf);
|
||||
errdefer shaper.deinit();
|
||||
|
||||
// Get our cell metrics based on a regular font ascii 'M'. Why 'M'?
|
||||
// Doesn't matter, any normal ASCII will do we're just trying to make
|
||||
// sure we use the regular font.
|
||||
const metrics = metrics: {
|
||||
const index = (try options.font_group.indexForCodepoint(alloc, 'M', .regular, .text)).?;
|
||||
const face = try options.font_group.group.faceFromIndex(index);
|
||||
break :metrics face.metrics;
|
||||
};
|
||||
log.debug("cell dimensions={}", .{metrics});
|
||||
|
||||
// Create our shader
|
||||
const program = try gl.Program.createVF(
|
||||
@embedFile("shaders/cell.v.glsl"),
|
||||
@embedFile("shaders/cell.f.glsl"),
|
||||
);
|
||||
|
||||
// Setup our font metrics uniform
|
||||
const metrics = try resetFontMetrics(alloc, program, options.font_group);
|
||||
|
||||
// Set our cell dimensions
|
||||
const pbind = try program.use();
|
||||
defer pbind.unbind();
|
||||
@ -314,19 +307,24 @@ pub fn deinit(self: *OpenGL) void {
|
||||
self.vao.destroy();
|
||||
self.program.destroy();
|
||||
|
||||
{
|
||||
self.resetCellsLRU();
|
||||
self.cells_lru.deinit(self.alloc);
|
||||
|
||||
self.cells.deinit(self.alloc);
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
fn resetCellsLRU(self: *OpenGL) void {
|
||||
// Our LRU values are array lists so we need to deallocate those first
|
||||
var it = self.cells_lru.queue.first;
|
||||
while (it) |node| {
|
||||
it = node.next;
|
||||
node.data.value.deinit(self.alloc);
|
||||
}
|
||||
|
||||
self.cells_lru.deinit(self.alloc);
|
||||
}
|
||||
|
||||
self.cells.deinit(self.alloc);
|
||||
self.* = undefined;
|
||||
// Initialize our new LRU
|
||||
self.cells_lru = CellsLRU.init(0);
|
||||
}
|
||||
|
||||
/// Returns the hints that we want for this
|
||||
@ -448,15 +446,69 @@ pub fn threadExit(self: *const OpenGL) void {
|
||||
}
|
||||
|
||||
/// Callback when the focus changes for the terminal this is rendering.
|
||||
///
|
||||
/// Must be called on the render thread.
|
||||
pub fn setFocus(self: *OpenGL, focus: bool) !void {
|
||||
self.focused = focus;
|
||||
}
|
||||
|
||||
/// Called to toggle the blink state of the cursor
|
||||
///
|
||||
/// Must be called on the render thread.
|
||||
pub fn blinkCursor(self: *OpenGL, reset: bool) void {
|
||||
self.cursor_visible = reset or !self.cursor_visible;
|
||||
}
|
||||
|
||||
/// Set the new font size.
|
||||
///
|
||||
/// Must be called on the render thread.
|
||||
pub fn setFontSize(self: *OpenGL, size: font.face.DesiredSize) !void {
|
||||
// Set our new size, this will also reset our font atlas.
|
||||
try self.font_group.setSize(size);
|
||||
|
||||
// Invalidate our cell cache.
|
||||
self.resetCellsLRU();
|
||||
|
||||
// Reset our GPU uniforms
|
||||
const metrics = try resetFontMetrics(self.alloc, self.program, self.font_group);
|
||||
|
||||
// Recalculate our cell size. If it is the same as before, then we do
|
||||
// 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.cell_size, new_cell_size)) return;
|
||||
|
||||
// Notify the window that the cell size changed.
|
||||
}
|
||||
|
||||
/// Reload the font metrics, recalculate cell size, and send that all
|
||||
/// down to the GPU.
|
||||
fn resetFontMetrics(
|
||||
alloc: Allocator,
|
||||
program: gl.Program,
|
||||
font_group: *font.GroupCache,
|
||||
) !font.face.Metrics {
|
||||
// Get our cell metrics based on a regular font ascii 'M'. Why 'M'?
|
||||
// Doesn't matter, any normal ASCII will do we're just trying to make
|
||||
// sure we use the regular font.
|
||||
const metrics = metrics: {
|
||||
const index = (try font_group.indexForCodepoint(alloc, 'M', .regular, .text)).?;
|
||||
const face = try font_group.group.faceFromIndex(index);
|
||||
break :metrics face.metrics;
|
||||
};
|
||||
log.debug("cell dimensions={}", .{metrics});
|
||||
|
||||
// Set our uniforms that rely on metrics
|
||||
const pbind = try program.use();
|
||||
defer pbind.unbind();
|
||||
try program.setUniform("cell_size", @Vector(2, f32){ metrics.cell_width, metrics.cell_height });
|
||||
try program.setUniform("underline_position", metrics.underline_position);
|
||||
try program.setUniform("underline_thickness", metrics.underline_thickness);
|
||||
try program.setUniform("strikethrough_position", metrics.strikethrough_position);
|
||||
try program.setUniform("strikethrough_thickness", metrics.strikethrough_thickness);
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
/// The primary render callback that is completely thread-safe.
|
||||
pub fn render(
|
||||
self: *OpenGL,
|
||||
@ -946,7 +998,7 @@ pub fn updateCell(
|
||||
|
||||
/// Returns the grid size for a given screen size. This is safe to call
|
||||
/// on any thread.
|
||||
pub fn gridSize(self: *OpenGL, screen_size: renderer.ScreenSize) renderer.GridSize {
|
||||
fn gridSize(self: *OpenGL, screen_size: renderer.ScreenSize) renderer.GridSize {
|
||||
return renderer.GridSize.init(
|
||||
screen_size.subPadding(self.padding.explicit),
|
||||
self.cell_size,
|
||||
|
@ -275,6 +275,10 @@ fn drainMailbox(self: *Thread) !void {
|
||||
_ = try self.cursor_h.again();
|
||||
}
|
||||
},
|
||||
|
||||
.font_size => |size| {
|
||||
try self.renderer.setFontSize(size);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const font = @import("../font/main.zig");
|
||||
|
||||
/// The messages that can be sent to a renderer thread.
|
||||
pub const Message = union(enum) {
|
||||
@ -12,4 +13,9 @@ pub const Message = union(enum) {
|
||||
/// Reset the cursor blink by immediately showing the cursor then
|
||||
/// restarting the timer.
|
||||
reset_cursor_blink: void,
|
||||
|
||||
/// Change the font size. This should recalculate the grid size and
|
||||
/// send a grid size change message back to the window thread if
|
||||
/// the size changes.
|
||||
font_size: font.face.DesiredSize,
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
const App = @import("../App.zig");
|
||||
const Window = @import("../Window.zig");
|
||||
const renderer = @import("../renderer.zig");
|
||||
|
||||
/// The message types that can be sent to a single window.
|
||||
pub const Message = union(enum) {
|
||||
|
Reference in New Issue
Block a user