better fonts part 1
This commit is contained in:
parent
818382f37b
commit
52ea7dcfa5
@ -32,8 +32,6 @@ const Glyph = struct {
|
||||
|
||||
st0 : rl.Vector2,
|
||||
st1 : rl.Vector2,
|
||||
|
||||
bitmap : []u8,
|
||||
};
|
||||
|
||||
pub const Font = struct {
|
||||
@ -49,25 +47,9 @@ pub const Font = struct {
|
||||
|
||||
const font_data = try std.fs.cwd().readFileAlloc(allocator, filename, 10 * 1024 * 1024);
|
||||
|
||||
|
||||
// if !success {
|
||||
// log("[Error] Could not read the font file.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
var face = try ft_lib.createFaceMemory(font_data, 0);
|
||||
var glyphs = std.AutoHashMap(u32, Glyph).init(allocator);
|
||||
// .FT_New_Memory_Face(ftlib, font_data.data, xx font_data.count, 0, *face);
|
||||
// if error {
|
||||
// log("[Error] %", to_string(FT_Error_String(error)));
|
||||
// }
|
||||
|
||||
//FT_Set_Pixel_Sizes(face, 0, size);
|
||||
try face.setCharSize(0, size * 64, 0, 96);
|
||||
// error = FT_Set_Char_Size(face, 0, size * 64, 0, 96);
|
||||
// if error {
|
||||
// log("[Error] %", to_string(FT_Error_String(error)));
|
||||
// }
|
||||
|
||||
var rects = try std.ArrayList(rp.stbrp_rect).initCapacity(allocator, 1024);
|
||||
defer rects.deinit(allocator);
|
||||
@ -79,8 +61,9 @@ pub const Font = struct {
|
||||
|
||||
const _atlas : []u8 = try allocator.alloc(u8, ATLAS_SIZE * ATLAS_SIZE);
|
||||
defer allocator.free(_atlas);
|
||||
@memset(_atlas, 0);
|
||||
|
||||
var atlas : rl.Image = .{
|
||||
const atlas : rl.Image = .{
|
||||
.data = _atlas.ptr,
|
||||
.width = ATLAS_SIZE,
|
||||
.height = ATLAS_SIZE,
|
||||
@ -88,35 +71,67 @@ pub const Font = struct {
|
||||
.format = .uncompressed_grayscale
|
||||
};
|
||||
|
||||
std.log.info("We have {} glyphs", .{face.numGlyphs()});
|
||||
// for (0..1500) |i| {
|
||||
for (0..face.numGlyphs()) |i| {
|
||||
//for 65..90 {
|
||||
//index := FT_Get_Char_Index(face, xx it);
|
||||
try face.loadGlyph(@intCast(i), .{ .render = true });
|
||||
try face.loadGlyph(@intCast(i), .{});
|
||||
const bmp = face.glyph().bitmap();
|
||||
|
||||
// array_add(*rects, stbrp_rect.{cast(s32) face.glyph.glyph_index, cast(s32) face.glyph.bitmap.width,
|
||||
// cast(s32) face.glyph.bitmap.rows, 0, 0, 0});
|
||||
try rects.append(allocator,
|
||||
rp.stbrp_rect{
|
||||
std.log.info("got size {}, {}", .{bmp.width(), bmp.rows()});
|
||||
|
||||
try rects.append(allocator, .{
|
||||
.id = @intCast(face.glyph().glyphIndex()),
|
||||
.w = @intCast(face.glyph().bitmap().width()),
|
||||
.h = @intCast(face.glyph().bitmap().rows()),
|
||||
.w = @intCast(bmp.width()),
|
||||
.h = @intCast(bmp.rows()),
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.was_packed = 0,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const width = face.glyph().bitmap().width();
|
||||
const height = face.glyph().bitmap().rows();
|
||||
_ = rp.stbrp_pack_rects(&stbrpcontext, rects.items.ptr, @intCast(rects.items.len));
|
||||
|
||||
for (rects.items) |rect| {
|
||||
if (rect.was_packed == 0) continue;
|
||||
const i : u32 = @intCast(rect.id);
|
||||
//index := FT_Get_Char_Index(face, xx it);
|
||||
try face.loadGlyph(i, .{ .render = true });
|
||||
|
||||
const bmp = face.glyph().bitmap();
|
||||
const buf = bmp.buffer() orelse continue;
|
||||
|
||||
const pitch: usize = @intCast(bmp.pitch());
|
||||
const w: usize = @intCast(bmp.width());
|
||||
const h: usize = @intCast(bmp.rows());
|
||||
|
||||
const dst_x: usize = @intCast(rect.x);
|
||||
const dst_y: usize = @intCast(rect.y);
|
||||
|
||||
for (0..h) |y| {
|
||||
const src = buf[y * pitch .. y * pitch + w];
|
||||
|
||||
const dst_index = (dst_y + y) * ATLAS_SIZE + dst_x;
|
||||
const dst = _atlas[dst_index .. dst_index + w];
|
||||
|
||||
@memcpy(dst, src);
|
||||
}
|
||||
|
||||
const width = bmp.width();
|
||||
const height = bmp.rows();
|
||||
const bearing_y = face.glyph().bitmapTop();
|
||||
const descent = @as(i32, @intCast(height)) - bearing_y;
|
||||
const ascent = @as(i32, @intCast(height)) - descent;
|
||||
|
||||
const x : i16 = @intCast(rect.x);
|
||||
const y : i16 = @as(i16, @intCast(rect.y)) + @as(i16, @intCast(height));
|
||||
|
||||
const fx = @as(f32, @floatFromInt(x));
|
||||
const fy = @as(f32, @floatFromInt(y));
|
||||
const fw = @as(f32, @floatFromInt(width));
|
||||
const fh = @as(f32, @floatFromInt(height));
|
||||
const fs = @as(f32, ATLAS_SIZE);
|
||||
|
||||
const glyph = Glyph{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.x = x,
|
||||
.y = y,
|
||||
.utf32 = @intCast(i),
|
||||
.index = face.glyph().glyphIndex(),
|
||||
.bearing_x = face.glyph().bitmapLeft(),
|
||||
@ -128,77 +143,15 @@ pub const Font = struct {
|
||||
.descent = @as(i32, @intCast(face.glyph().bitmap().rows())) - face.glyph().bitmapTop(),
|
||||
.ascent = ascent,
|
||||
.advance = @intCast(face.glyph().advance().x >> 6),
|
||||
.st0 = rl.Vector2.zero(),
|
||||
.st1 = rl.Vector2.zero(),
|
||||
.bitmap = try allocator.alloc(u8, width * height),
|
||||
.st0 = rl.Vector2.init((fx + 0.5) / fs, (fy - 0.5) / fs),
|
||||
.st1 = .{.x = (fx + fw) / fs, .y = (fy - fh) / fs},
|
||||
};
|
||||
const s = glyph.height * glyph.width;
|
||||
const buf = face.glyph().bitmap().buffer() orelse continue;
|
||||
@memcpy(glyph.bitmap, buf[0..s]);
|
||||
|
||||
// table_set(*font.glyphs, glyph.index, glyph);
|
||||
try glyphs.put(glyph.index, glyph);
|
||||
// if (try glyphs.fetchPut(glyph.index, glyph)) |old| {
|
||||
// allocator.free(old.value.bitmap);
|
||||
// }
|
||||
}
|
||||
|
||||
_ = rp.stbrp_pack_rects(&stbrpcontext, rects.items.ptr, @intCast(rects.items.len));
|
||||
// stbrp_pack_rects(*stbrpcontext, rects.data, cast(s32) rects.count);
|
||||
|
||||
for (rects.items) |rect| {
|
||||
// for rect : rects {
|
||||
const glyph = glyphs.getPtr(@intCast(rect.id)) orelse continue;
|
||||
if (glyph.bitmap.len != 0) {
|
||||
glyph.x = @intCast(rect.x);
|
||||
glyph.y = @as(i16, @intCast(rect.y)) + @as(i16, @intCast(glyph.height));
|
||||
|
||||
const fx = @as(f32, @floatFromInt(glyph.x));
|
||||
const fy = @as(f32, @floatFromInt(glyph.y));
|
||||
const fw = @as(f32, @floatFromInt(glyph.width));
|
||||
const fh = @as(f32, @floatFromInt(glyph.height));
|
||||
const fs = @as(f32, ATLAS_SIZE);
|
||||
|
||||
glyph.st0 = rl.Vector2.init((fx + 0.5) / fs, (fy - 0.5) / fs);
|
||||
|
||||
glyph.st1 = .{
|
||||
.x = (fx + fw) / fs,
|
||||
.y = (fy - fh) / fs,
|
||||
};
|
||||
|
||||
const g = rl.Image{
|
||||
.data = glyph.bitmap.ptr,
|
||||
.width = @intCast(glyph.width),
|
||||
.height = @intCast(glyph.height),
|
||||
.mipmaps = 1,
|
||||
.format = .uncompressed_grayscale
|
||||
};
|
||||
|
||||
atlas.drawImage(g,
|
||||
.{ .x = 0, .y = 0, .width = @floatFromInt(g.width), .height = @floatFromInt(g.height) },
|
||||
.{ .x = @floatFromInt(rect.x), .y = @floatFromInt(rect.y), .width = @floatFromInt(g.width), .height = @floatFromInt(g.height)},
|
||||
.white
|
||||
);
|
||||
|
||||
// copyBitmapToAtlas(glyph.bitmap, glyph.width, glyph.height, atlas, @intCast(rect.x), @intCast(rect.y));
|
||||
}
|
||||
// glyph : *Glyph = table_find_pointer(*font.glyphs, cast(u32) rect.id);
|
||||
// if (glyph.bitmap) {
|
||||
// glyph.x = cast,trunc(s16, rect.x);
|
||||
// glyph.y = cast,trunc(s16, rect.y) + xx glyph.height;
|
||||
// glyph.st0 = .{cast(float, glyph.x + 0.5) / ATLAS_SIZE, cast(float, glyph.y - 0.5) / ATLAS_SIZE};
|
||||
// //glyph.st1 = glyph.st0 + .{cast(float, glyph.width) / ATLAS_SIZE, -cast(float, glyph.height) / ATLAS_SIZE};
|
||||
// glyph.st1 = .{(cast(float, glyph.x + glyph.width )) / cast(float, ATLAS_SIZE), (cast(float, glyph.y - glyph.height )) / cast(float, ATLAS_SIZE)};
|
||||
// copyBitmapToAtlas(glyph.bitmap, cast(s32) glyph.width, cast(s32) glyph.height, atlas, cast(s32) rect.x, cast(s32) rect.y);
|
||||
// }
|
||||
}
|
||||
|
||||
const texture = try rl.Texture.fromImage(atlas);
|
||||
|
||||
// image.flipVertical();
|
||||
// texture = make_texture_from_data(atlas, ATLAS_SIZE, ATLAS_SIZE);
|
||||
|
||||
// const kb = kbts_FontFromMemory(font_data.data, xx font_data.count, 0, null, null);
|
||||
var _kb = kb.kbts_FontFromMemory(font_data.ptr, @intCast(font_data.len), 0, null, null);
|
||||
|
||||
if (kb.kbts_FontIsValid(&_kb) != 0) {
|
||||
@ -215,10 +168,10 @@ pub const Font = struct {
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Font, allocator: std.mem.Allocator) void {
|
||||
var it = self.glyphs.valueIterator();
|
||||
while (it.next()) |g| {
|
||||
allocator.free(g.bitmap);
|
||||
}
|
||||
// var it = self.glyphs.valueIterator();
|
||||
// while (it.next()) |g| {
|
||||
// allocator.free(g.bitmap);
|
||||
// }
|
||||
self.glyphs.deinit();
|
||||
self.face.deinit();
|
||||
kb.kbts_FreeFont(&self.kb);
|
||||
@ -314,9 +267,9 @@ pub const Font = struct {
|
||||
rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st1.y); rl.gl.rlVertex2f(p1.x, p1.y);
|
||||
rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st0.x, st1.y); rl.gl.rlVertex2f(p0.x, p1.y);
|
||||
|
||||
rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st0.y); rl.gl.rlVertex2f(p1.x, p0.y);
|
||||
rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st1.y); rl.gl.rlVertex2f(p1.x, p1.y);
|
||||
rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st0.x, st0.y); rl.gl.rlVertex2f(p0.x, p0.y);
|
||||
// rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st0.y); rl.gl.rlVertex2f(p1.x, p0.y);
|
||||
// rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st1.y); rl.gl.rlVertex2f(p1.x, p1.y);
|
||||
// rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st0.x, st0.y); rl.gl.rlVertex2f(p0.x, p0.y);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -180,17 +180,22 @@ pub fn main() !void {
|
||||
|
||||
rl.beginDrawing();
|
||||
|
||||
f.texture.drawPro(
|
||||
.{.x = 0, .y = 0, .width = 4096, .height = 4096},
|
||||
.{.x = 0, .y = 0, .width = 512, .height = 512 },
|
||||
.zero(), 0, .white);
|
||||
|
||||
rl.beginShaderMode(shader);
|
||||
|
||||
f.render_text(
|
||||
"H",
|
||||
rl.Vector2.init(400, 400),
|
||||
true,
|
||||
rl.Color.white,
|
||||
rl.Color.blank,
|
||||
true,
|
||||
true
|
||||
);
|
||||
// f.render_text(
|
||||
// "H",
|
||||
// rl.Vector2.init(400, 400),
|
||||
// true,
|
||||
// rl.Color.white,
|
||||
// rl.Color.blank,
|
||||
// true,
|
||||
// true
|
||||
// );
|
||||
|
||||
|
||||
// rl.gl.rlBegin(rl.gl.rl_triangles);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user