font: render sprites with a configurable grid cell width

Fixes #666
This commit is contained in:
Mitchell Hashimoto
2023-10-13 14:31:55 -07:00
parent d66d2c8827
commit 7995d44cfb
6 changed files with 20 additions and 7 deletions

View File

@ -515,6 +515,7 @@ pub fn renderGlyph(
alloc, alloc,
atlas, atlas,
glyph_index, glyph_index,
opts,
), ),
}; };

View File

@ -41,6 +41,7 @@ const CodepointKey = struct {
const GlyphKey = struct { const GlyphKey = struct {
index: Group.FontIndex, index: Group.FontIndex,
glyph: u32, glyph: u32,
opts: font.face.RenderOptions,
}; };
/// The GroupCache takes ownership of Group and will free it. /// The GroupCache takes ownership of Group and will free it.
@ -124,7 +125,7 @@ pub fn renderGlyph(
glyph_index: u32, glyph_index: u32,
opts: font.face.RenderOptions, opts: font.face.RenderOptions,
) !Glyph { ) !Glyph {
const key: GlyphKey = .{ .index = index, .glyph = glyph_index }; const key: GlyphKey = .{ .index = index, .glyph = glyph_index, .opts = opts };
const gop = try self.glyphs.getOrPut(alloc, key); const gop = try self.glyphs.getOrPut(alloc, key);
// If it is in the cache, use it. // If it is in the cache, use it.

View File

@ -76,6 +76,10 @@ pub const RenderOptions = struct {
/// is typically naive, but ultimately up to the rasterizer. /// is typically naive, but ultimately up to the rasterizer.
max_height: ?u16 = null, max_height: ?u16 = null,
/// The number of grid cells this glyph will take up. This can be used
/// optionally by the rasterizer to better layout the glyph.
cell_width: ?u2 = null,
/// Thicken the glyph. This draws the glyph with a thicker stroke width. /// Thicken the glyph. This draws the glyph with a thicker stroke width.
/// This is purely an aesthetic setting. /// This is purely an aesthetic setting.
/// ///

View File

@ -49,6 +49,7 @@ pub fn renderGlyph(
alloc: Allocator, alloc: Allocator,
atlas: *font.Atlas, atlas: *font.Atlas,
cp: u32, cp: u32,
opts: font.face.RenderOptions,
) !font.Glyph { ) !font.Glyph {
if (std.debug.runtime_safety) { if (std.debug.runtime_safety) {
if (!self.hasCodepoint(cp, null)) { if (!self.hasCodepoint(cp, null)) {
@ -57,11 +58,17 @@ pub fn renderGlyph(
} }
} }
// We adjust our sprite width based on the cell width.
const width = switch (opts.cell_width orelse 1) {
0, 1 => self.width,
else => |width| self.width * width,
};
// Safe to ".?" because of the above assertion. // Safe to ".?" because of the above assertion.
return switch (Kind.init(cp).?) { return switch (Kind.init(cp).?) {
.box => box: { .box => box: {
const f: Box = .{ const f: Box = .{
.width = self.width, .width = width,
.height = self.height, .height = self.height,
.thickness = self.thickness, .thickness = self.thickness,
}; };
@ -73,7 +80,7 @@ pub fn renderGlyph(
alloc, alloc,
atlas, atlas,
@enumFromInt(cp), @enumFromInt(cp),
self.width, width,
self.height, self.height,
self.underline_position, self.underline_position,
self.thickness, self.thickness,

View File

@ -1364,7 +1364,7 @@ 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 },
); );
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;
@ -1421,7 +1421,7 @@ fn addCursor(
self.alloc, self.alloc,
font.sprite_index, font.sprite_index,
@intFromEnum(sprite), @intFromEnum(sprite),
.{}, .{ .cell_width = if (cell.attrs.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;

View File

@ -872,7 +872,7 @@ fn addCursor(
self.alloc, self.alloc,
font.sprite_index, font.sprite_index,
@intFromEnum(sprite), @intFromEnum(sprite),
.{}, .{ .cell_width = if (cell.attrs.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;
@ -1136,7 +1136,7 @@ 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 },
); );
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;