DVUI

glyphInfoGenerate

Parameters

#
self:*Entry
*Entry
codepoint:u32
u32

Source

Implementation

#
pub fn glyphInfoGenerate(self: *Entry, codepoint: u32) Error!GlyphInfo {
            const gi: GlyphInfo = if (impl == .FreeType) blk: {
                FreeType.intToError(c.FT_Load_Char(self.face, codepoint, @as(i32, @bitCast(FreeType.LoadFlags{ .render = false })))) catch |err| {
                    dvui.log.warn("glyphInfoGet freetype error {any} font {s} codepoint {d}\n", .{ err, self.name, codepoint });
                    return Error.FontError;
                };

                const m = self.face.*.glyph.*.metrics;
                const minx = @as(f32, @floatFromInt(m.horiBearingX)) / 64.0;
                const miny = @as(f32, @floatFromInt(m.horiBearingY)) / 64.0;

                //const hx = @as(f32, @floatFromInt(m.horiBearingX)) / 64.0;
                //const w = @as(f32, @floatFromInt(m.width)) / 64.0;
                //const hy = @as(f32, @floatFromInt(m.horiBearingY)) / 64.0;
                //const h = @as(f32, @floatFromInt(m.height)) / 64.0;
                const adv = @as(f32, @floatFromInt(m.horiAdvance)) / 64.0;
                //std.debug.print("{c},{d},{d},{d},{d},{d},{d}\n", .{@as(u8, @intCast(codepoint)), codepoint, hx, w, hy, h, adv});

                // All these values should be integers, but just in case.
                // bitmap assumes pen position is at a pixel boundary.

                break :blk .{
                    .advance = adv,
                    .leftBearing = @floor(minx),
                    .topBearing = @floor(miny),
                    .w = @ceil(minx + @as(f32, @floatFromInt(m.width)) / 64.0) - @floor(minx),
                    .h = @ceil(miny + @as(f32, @floatFromInt(m.height)) / 64.0) - @floor(miny),
                    .uv = .{ 0, 0 },
                };
            } else blk: {
                var advanceWidth: c_int = undefined;
                c.stbtt_GetCodepointHMetrics(&self.face, @as(c_int, @intCast(codepoint)), &advanceWidth, null);
                var ix0: c_int = undefined;
                var iy0: c_int = undefined;
                var ix1: c_int = undefined;
                var iy1: c_int = undefined;
                const ret = c.stbtt_GetCodepointBox(&self.face, @as(c_int, @intCast(codepoint)), &ix0, &iy0, &ix1, &iy1);
                const x0: f32 = if (ret == 0) 0 else self.scaleFactor * @as(f32, @floatFromInt(ix0));
                const y0: f32 = if (ret == 0) 0 else self.scaleFactor * @as(f32, @floatFromInt(iy0));
                const x1: f32 = if (ret == 0) 0 else self.scaleFactor * @as(f32, @floatFromInt(ix1));
                const y1: f32 = if (ret == 0) 0 else self.scaleFactor * @as(f32, @floatFromInt(iy1));
                const adv: f32 = self.scaleFactor * @as(f32, @floatFromInt(advanceWidth));

                //std.debug.print("{c},{d},{d},{d},{d},{d},{d}\n", .{@as(u8, @intCast(codepoint)), codepoint, x0, x1, y0, y1, adv});
                //std.debug.print("{d} codepoint {d} stbtt x0 {d} {d} x1 {d} {d} y0 {d} {d} y1 {d} {d}\n", .{ self.ascent, codepoint, ix0, x0, ix1, x1, iy0, y0, iy1, y1 });

                // bitmap assumes pen position is at a pixel boundary, so we
                // extend the box in each direction to a full pixel (so floor
                // x0/y0, and ceil x1/y1)

                break :blk .{
                    .advance = adv,
                    .leftBearing = @floor(x0),
                    .topBearing = @ceil(y1),
                    .w = @ceil(x1) - @floor(x0),
                    .h = @ceil(y1) - @floor(y0),
                    .uv = .{ 0, 0 },
                };
            };
            //std.debug.print("codepoint {d} advance {d} leftBearing {d} topBearing {d} w {d} h {d}\n", .{ codepoint, gi.advance, gi.leftBearing, gi.topBearing, gi.w, gi.h });
            return gi;
        }