finish win32 gui support for double-wide characters
This commit is contained in:
parent
8278a080af
commit
05b87b1406
3 changed files with 25 additions and 7 deletions
|
@ -75,6 +75,7 @@ pub fn render(
|
|||
self: *const DwriteRenderer,
|
||||
font: Font,
|
||||
utf8: []const u8,
|
||||
double_width: bool,
|
||||
) void {
|
||||
var utf16_buf: [10]u16 = undefined;
|
||||
const utf16_len = std.unicode.utf8ToUtf16Le(&utf16_buf, utf8) catch unreachable;
|
||||
|
@ -85,7 +86,10 @@ pub fn render(
|
|||
const rect: win32.D2D_RECT_F = .{
|
||||
.left = 0,
|
||||
.top = 0,
|
||||
.right = @floatFromInt(font.cell_size.x),
|
||||
.right = if (double_width)
|
||||
@as(f32, @floatFromInt(font.cell_size.x)) * @as(f32, @floatFromInt(font.cell_size.x))
|
||||
else
|
||||
@as(f32, @floatFromInt(font.cell_size.x)),
|
||||
.bottom = @floatFromInt(font.cell_size.y),
|
||||
};
|
||||
self.render_target.BeginDraw();
|
||||
|
|
|
@ -149,7 +149,7 @@ pub const WindowState = struct {
|
|||
}
|
||||
|
||||
// TODO: this should take a utf8 graphme instead
|
||||
pub fn generateGlyph(state: *WindowState, font: Font, codepoint: u21, right_half: bool) u32 {
|
||||
pub fn generateGlyph(state: *WindowState, font: Font, codepoint: u21, kind: enum { single, left, right }) u32 {
|
||||
// for now we'll just use 1 texture and leverage the entire thing
|
||||
const texture_cell_count: XY(u16) = getD3d11TextureMaxCellCount(font.cell_size);
|
||||
const texture_cell_count_total: u32 =
|
||||
|
@ -184,6 +184,11 @@ pub const WindowState = struct {
|
|||
break :blk &(state.glyph_index_cache.?);
|
||||
};
|
||||
|
||||
const right_half: bool = switch (kind) {
|
||||
.single, .left => false,
|
||||
.right => true,
|
||||
};
|
||||
|
||||
switch (glyph_index_cache.reserve(
|
||||
global.glyph_cache_arena.allocator(),
|
||||
codepoint,
|
||||
|
@ -194,8 +199,11 @@ pub const WindowState = struct {
|
|||
// defer if (!render_success) state.glyph_index_cache.remove(reserved.index);
|
||||
const pos: XY(u16) = cellPosFromIndex(reserved.index, texture_cell_count.x);
|
||||
const coord = coordFromCellPos(font.cell_size, pos);
|
||||
var staging_size = font.cell_size;
|
||||
staging_size.x = if (right_half) staging_size.x * 2 else staging_size.x;
|
||||
const staging_size: XY(u16) = .{
|
||||
// twice the width to handle double-wide glyphs
|
||||
.x = font.cell_size.x * 2,
|
||||
.y = font.cell_size.y,
|
||||
};
|
||||
const staging = global.staging_texture.update(staging_size);
|
||||
var utf8_buf: [7]u8 = undefined;
|
||||
const utf8_len: u3 = std.unicode.utf8Encode(codepoint, &utf8_buf) catch |e| std.debug.panic(
|
||||
|
@ -205,6 +213,10 @@ pub const WindowState = struct {
|
|||
staging.text_renderer.render(
|
||||
font,
|
||||
utf8_buf[0..utf8_len],
|
||||
switch (kind) {
|
||||
.single => false,
|
||||
.left, .right => true,
|
||||
},
|
||||
);
|
||||
const box: win32.D3D11_BOX = .{
|
||||
.left = if (right_half) font.cell_size.x else 0,
|
||||
|
@ -292,7 +304,7 @@ pub fn paint(
|
|||
}
|
||||
|
||||
const copy_col_count: u16 = @min(col_count, shader_col_count);
|
||||
const blank_space_glyph_index = state.generateGlyph(font, ' ', false);
|
||||
const blank_space_glyph_index = state.generateGlyph(font, ' ', .single);
|
||||
|
||||
const cell_count: u32 = @as(u32, shader_col_count) * @as(u32, shader_row_count);
|
||||
state.shader_cells.updateCount(cell_count);
|
||||
|
|
|
@ -1083,6 +1083,7 @@ fn WndProc(
|
|||
) catch |e| oom(e);
|
||||
var prev_width: usize = 1;
|
||||
var prev_cell: render.Cell = undefined;
|
||||
var prev_codepoint: u21 = undefined;
|
||||
for (global.screen.buf, global.render_cells.items) |*screen_cell, *render_cell| {
|
||||
const width = screen_cell.char.width;
|
||||
const codepoint = if (std.unicode.utf8ValidateSlice(screen_cell.char.grapheme))
|
||||
|
@ -1091,16 +1092,17 @@ fn WndProc(
|
|||
std.unicode.replacement_character;
|
||||
if (prev_width > 1) {
|
||||
render_cell.* = prev_cell;
|
||||
render_cell.glyph_index = state.render_state.generateGlyph(font, codepoint, true);
|
||||
render_cell.glyph_index = state.render_state.generateGlyph(font, prev_codepoint, .right);
|
||||
} else {
|
||||
render_cell.* = .{
|
||||
.glyph_index = state.render_state.generateGlyph(font, codepoint, false),
|
||||
.glyph_index = state.render_state.generateGlyph(font, codepoint, if (width == 1) .single else .left),
|
||||
.background = renderColorFromVaxis(screen_cell.style.bg),
|
||||
.foreground = renderColorFromVaxis(screen_cell.style.fg),
|
||||
};
|
||||
}
|
||||
prev_width = width;
|
||||
prev_cell = render_cell.*;
|
||||
prev_codepoint = codepoint;
|
||||
}
|
||||
render.paint(
|
||||
&state.render_state,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue