examples/gkurve: support for UTF32 characters

This commit is contained in:
PiergiorgioZagaria 2022-06-05 18:05:15 +02:00 committed by Stephen Gutekanst
parent 98138dd2fa
commit c1b3996b63
3 changed files with 18 additions and 9 deletions

View file

@ -21,7 +21,7 @@ const GlyphInfo = struct {
face: ft.Face, face: ft.Face,
size: i32, size: i32,
char_map: std.AutoHashMap(u8, GlyphInfo), char_map: std.AutoHashMap(u21, GlyphInfo),
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
const WriterContext = struct { const WriterContext = struct {
@ -48,7 +48,7 @@ pub fn init(lib: ft.Library, font_path: []const u8, face_index: i32, char_size:
return Label{ return Label{
.face = try lib.newFace(font_path, face_index), .face = try lib.newFace(font_path, face_index),
.size = char_size, .size = char_size,
.char_map = std.AutoHashMap(u8, GlyphInfo).init(allocator), .char_map = std.AutoHashMap(u21, GlyphInfo).init(allocator),
.allocator = allocator, .allocator = allocator,
}; };
} }
@ -60,7 +60,11 @@ pub fn deinit(label: *Label) void {
fn write(ctx: WriterContext, bytes: []const u8) WriterError!usize { fn write(ctx: WriterContext, bytes: []const u8) WriterError!usize {
var offset = Vec2{ 0, 0 }; var offset = Vec2{ 0, 0 };
for (bytes) |char| { var j: usize = 0;
while (j < bytes.len) {
const len = std.unicode.utf8ByteSequenceLength(bytes[j]) catch unreachable;
const char = std.unicode.utf8Decode(bytes[j..(j + len)]) catch unreachable;
j += len;
switch (char) { switch (char) {
'\n' => { '\n' => {
offset[0] = 0; offset[0] = 0;

View file

@ -94,15 +94,16 @@ pub fn init(app: *App, engine: *mach.Engine) !void {
defer lib.deinit(); defer lib.deinit();
const size_multiplier = 5; const size_multiplier = 5;
const character = 'e'; const character = "è";
var label = try Label.init(lib, "freetype/upstream/assets/FiraSans-Regular.ttf", 0, 110 * size_multiplier, engine.allocator); var label = try Label.init(lib, "freetype/upstream/assets/FiraSans-Regular.ttf", 0, 110 * size_multiplier, engine.allocator);
defer label.deinit(); defer label.deinit();
try label.print(app, &.{character}, .{}, @Vector(2, f32){ 50 * size_multiplier, 40 }, @Vector(4, f32){ 1, 1, 1, 1 }); // try label.print(app, "All your game's bases are belong to us èçòà", .{}, @Vector(2, f32){ 0, 420 }, @Vector(4, f32){ 1, 1, 1, 1 });
try label.print(app, character, .{}, @Vector(2, f32){ 50 * size_multiplier, 40 }, @Vector(4, f32){ 1, 1, 1, 1 });
var resizable_label: ResizableLabel = undefined; var resizable_label: ResizableLabel = undefined;
try resizable_label.init(lib, "freetype/upstream/assets/FiraSans-Regular.ttf", 0, engine.allocator, white_texture_uv_data); try resizable_label.init(lib, "freetype/upstream/assets/FiraSans-Regular.ttf", 0, engine.allocator, white_texture_uv_data);
defer resizable_label.deinit(); defer resizable_label.deinit();
try resizable_label.print(app, &.{character}, .{}, @Vector(4, f32){ 0, 40, 0, 0 }, @Vector(4, f32){ 1, 1, 1, 1 }, 80 * size_multiplier); try resizable_label.print(app, character, .{}, @Vector(4, f32){ 0, 40, 0, 0 }, @Vector(4, f32){ 1, 1, 1, 1 }, 80 * size_multiplier);
queue.writeTexture( queue.writeTexture(
&.{ .texture = texture }, &.{ .texture = texture },

View file

@ -34,7 +34,7 @@ const CharVertices = struct {
}; };
face: ft.Face, face: ft.Face,
char_map: std.AutoHashMap(u8, CharVertices), char_map: std.AutoHashMap(u21, CharVertices),
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
tessellator: Tessellator, tessellator: Tessellator,
white_texture: UVData, white_texture: UVData,
@ -66,7 +66,7 @@ pub fn writer(label: *ResizableLabel, app: *App, position: Vec4, text_color: Vec
pub fn init(self: *ResizableLabel, lib: ft.Library, font_path: []const u8, face_index: i32, allocator: std.mem.Allocator, white_texture: UVData) !void { pub fn init(self: *ResizableLabel, lib: ft.Library, font_path: []const u8, face_index: i32, allocator: std.mem.Allocator, white_texture: UVData) !void {
self.* = ResizableLabel{ self.* = ResizableLabel{
.face = try lib.newFace(font_path, face_index), .face = try lib.newFace(font_path, face_index),
.char_map = std.AutoHashMap(u8, CharVertices).init(allocator), .char_map = std.AutoHashMap(u21, CharVertices).init(allocator),
.allocator = allocator, .allocator = allocator,
.tessellator = undefined, .tessellator = undefined,
.white_texture = white_texture, .white_texture = white_texture,
@ -94,7 +94,11 @@ pub fn deinit(label: *ResizableLabel) void {
// FIXME: many useless allocations for the arraylists // FIXME: many useless allocations for the arraylists
fn write(ctx: WriterContext, bytes: []const u8) WriterError!usize { fn write(ctx: WriterContext, bytes: []const u8) WriterError!usize {
var offset = Vec4{ 0, 0, 0, 0 }; var offset = Vec4{ 0, 0, 0, 0 };
for (bytes) |char| { var c: usize = 0;
while (c < bytes.len) {
const len = std.unicode.utf8ByteSequenceLength(bytes[c]) catch unreachable;
const char = std.unicode.utf8Decode(bytes[c..(c + len)]) catch unreachable;
c += len;
switch (char) { switch (char) {
'\n' => { '\n' => {
offset[0] = 0; offset[0] = 0;