switch to pure Zig font atlas

This commit is contained in:
Mitchell Hashimoto
2022-04-05 19:54:13 -07:00
parent d51ed2536c
commit 388c0056c9
3 changed files with 37 additions and 30 deletions

View File

@ -4,12 +4,18 @@
const App = @This();
const std = @import("std");
const Allocator = std.mem.Allocator;
const glfw = @import("glfw");
const gl = @import("opengl.zig");
const TextRenderer = @import("TextRenderer.zig");
const TextRenderer = if (true)
@import("TextRenderer.zig")
else
@import("TextRenderer2.zig");
const log = std.log;
alloc: Allocator,
window: glfw.Window,
text: TextRenderer,
@ -17,7 +23,7 @@ text: TextRenderer,
/// Initialize the main app instance. This creates the main window, sets
/// up the renderer state, compiles the shaders, etc. This is the primary
/// "startup" logic.
pub fn init(alloc: std.mem.Allocator) !App {
pub fn init(alloc: Allocator) !App {
// Create our window
const window = try glfw.Window.create(640, 480, "ghostty", null, null, .{
.context_version_major = 3,
@ -57,13 +63,14 @@ pub fn init(alloc: std.mem.Allocator) !App {
}).callback);
return App{
.alloc = alloc,
.window = window,
.text = texter,
};
}
pub fn deinit(self: *App) void {
self.text.deinit();
self.text.deinit(self.alloc);
self.window.destroy();
self.* = undefined;
}

View File

@ -104,7 +104,7 @@ pub fn loadFaceFromMemory(self: *FontAtlas, source: [:0]const u8, size: u32) !vo
}
/// Get the glyph for the given codepoint.
pub fn getGlyph(self: *FontAtlas, v: anytype) ?*Glyph {
pub fn getGlyph(self: FontAtlas, v: anytype) ?*Glyph {
const utf32 = codepoint(v);
const entry = self.glyphs.getEntry(utf32) orelse return null;
return entry.value_ptr;
@ -170,8 +170,15 @@ pub fn addGlyph(self: *FontAtlas, alloc: Allocator, v: anytype) !void {
.t0 = @intToFloat(f32, region.y) / @intToFloat(f32, self.atlas.size),
.s1 = @intToFloat(f32, region.x + tgt_w) / @intToFloat(f32, self.atlas.size),
.t1 = @intToFloat(f32, region.y + tgt_h) / @intToFloat(f32, self.atlas.size),
.advance_x = @intToFloat(f32, glyph.*.advance.x),
.advance_x = f26dot6ToFloat(glyph.*.advance.x),
};
log.debug("loaded glyph codepoint={} glyph={}", .{ utf32, gop.value_ptr.* });
}
/// Convert 26.6 pixel format to f32
fn f26dot6ToFloat(v: ftc.FT_F26Dot6) f32 {
return @intToFloat(f32, v) / 64.0;
}
/// Returns the UTF-32 codepoint for the given value.

View File

@ -4,12 +4,14 @@ const std = @import("std");
const ftc = @import("freetype/c.zig");
const gl = @import("opengl.zig");
const gb = @import("gb_math.zig");
const ftgl = @import("freetype-gl/c.zig");
const Atlas = @import("Atlas.zig");
const FontAtlas = @import("FontAtlas.zig");
alloc: std.mem.Allocator,
projection: gb.gbMat4 = undefined,
font: *ftgl.texture_font_t,
atlas: *ftgl.texture_atlas_t,
font: FontAtlas,
atlas: Atlas,
program: gl.Program,
tex: gl.Texture,
@ -23,25 +25,16 @@ const Char = struct {
};
pub fn init(alloc: std.mem.Allocator) !TextRenderer {
const atlas = ftgl.texture_atlas_new(512, 512, 1);
if (atlas == null) return error.FontAtlasFail;
errdefer ftgl.texture_atlas_delete(atlas);
const font = ftgl.texture_font_new_from_memory(
atlas,
48,
face_ttf,
face_ttf.len,
);
if (font == null) return error.FontInitFail;
errdefer ftgl.texture_font_delete(font);
var atlas = try Atlas.init(alloc, 512);
errdefer atlas.deinit(alloc);
var font = try FontAtlas.init(atlas);
errdefer font.deinit(alloc);
try font.loadFaceFromMemory(face_ttf, 48);
// Load all visible ASCII characters.
var i: u8 = 32;
while (i < 127) : (i += 1) {
// Load the character
if (ftgl.texture_font_load_glyph(font, &i) == 0) {
return error.GlyphLoadFailed;
}
try font.addGlyph(alloc, i);
}
// Build our texture
@ -55,12 +48,12 @@ pub fn init(alloc: std.mem.Allocator) !TextRenderer {
try binding.image2D(
0,
.Red,
@intCast(c_int, atlas.*.width),
@intCast(c_int, atlas.*.height),
@intCast(c_int, atlas.size),
@intCast(c_int, atlas.size),
0,
.Red,
.UnsignedByte,
atlas.*.data,
atlas.data.ptr,
);
// Create our shader
@ -84,9 +77,9 @@ pub fn init(alloc: std.mem.Allocator) !TextRenderer {
return res;
}
pub fn deinit(self: *TextRenderer) void {
ftgl.texture_font_delete(self.font);
ftgl.texture_atlas_delete(self.atlas);
pub fn deinit(self: *TextRenderer, alloc: std.mem.Allocator) void {
self.font.deinit(alloc);
self.atlas.deinit(alloc);
self.* = undefined;
}
@ -125,7 +118,7 @@ pub fn render(
var curx: f32 = x;
for (text) |c, i| {
if (ftgl.texture_font_get_glyph(self.font, &c)) |glyph_ptr| {
if (self.font.getGlyph(c)) |glyph_ptr| {
const glyph = glyph_ptr.*;
const kerning = 0; // for now
curx += kerning;