coretext: handle glyph padding in region reservation

This commit is contained in:
Mitchell Hashimoto
2023-06-30 21:02:10 -07:00
parent 55254acaad
commit 5706770c38

View File

@ -104,11 +104,6 @@ pub const Face = struct {
glyph_index: u32, glyph_index: u32,
max_height: ?u16, max_height: ?u16,
) !font.Glyph { ) !font.Glyph {
// We add a small pixel padding around the edge of our glyph so that
// anti-aliasing and smoothing doesn't cause us to pick up the pixels
// of another glyph when packed into the atlas.
const padding = 1;
_ = max_height; _ = max_height;
var glyphs = [_]macos.graphics.Glyph{@intCast(glyph_index)}; var glyphs = [_]macos.graphics.Glyph{@intCast(glyph_index)};
@ -130,15 +125,15 @@ pub const Face = struct {
// The glyph height is basically rect.size.height but we do the // The glyph height is basically rect.size.height but we do the
// ascent plus the descent because both are rounded elements that // ascent plus the descent because both are rounded elements that
// will make us more accurate. // will make us more accurate.
const glyph_height: u32 = @intFromFloat(glyph_ascent + render_y); const height: u32 = @intFromFloat(glyph_ascent + render_y);
// The glyph width is our advertised bounding with plus the rounding // The glyph width is our advertised bounding with plus the rounding
// difference from our rendering X. // difference from our rendering X.
const glyph_width: u32 = @intFromFloat(@ceil(rect.size.width + (rect.origin.x - render_x))); const width: u32 = @intFromFloat(@ceil(rect.size.width + (rect.origin.x - render_x)));
// This bitmap is blank. I've seen it happen in a font, I don't know why. // This bitmap is blank. I've seen it happen in a font, I don't know why.
// If it is empty, we just return a valid glyph struct that does nothing. // If it is empty, we just return a valid glyph struct that does nothing.
if (glyph_width == 0 or glyph_height == 0) return font.Glyph{ if (width == 0 or height == 0) return font.Glyph{
.width = 0, .width = 0,
.height = 0, .height = 0,
.offset_x = 0, .offset_x = 0,
@ -148,11 +143,6 @@ pub const Face = struct {
.advance_x = 0, .advance_x = 0,
}; };
// Width and height. Note the padding doubling is because we want
// the padding on both sides (top/bottom, left/right).
const width = glyph_width + (padding * 2);
const height = glyph_height + (padding * 2);
// Settings that are specific to if we are rendering text or emoji. // Settings that are specific to if we are rendering text or emoji.
const color: struct { const color: struct {
color: bool, color: bool,
@ -238,12 +228,33 @@ pub const Face = struct {
// slightly off the edge of the bitmap. // slightly off the edge of the bitmap.
self.font.drawGlyphs(&glyphs, &.{ self.font.drawGlyphs(&glyphs, &.{
.{ .{
.x = padding + (-1 * render_x), .x = -1 * render_x,
.y = padding + render_y, .y = render_y,
}, },
}, ctx); }, ctx);
const region = try atlas.reserve(alloc, width, height); const region = region: {
// We need to add a 1px padding to the font so that we don't
// get fuzzy issues when blending textures.
const padding = 1;
// Get the full padded region
var region = try atlas.reserve(
alloc,
width + (padding * 2), // * 2 because left+right
height + (padding * 2), // * 2 because top+bottom
);
// Modify the region so that we remove the padding so that
// we write to the non-zero location. The data in an Altlas
// is always initialized to zero (Atlas.clear) so we don't
// need to worry about zero-ing that.
region.x += padding;
region.y += padding;
region.width -= padding * 2;
region.height -= padding * 2;
break :region region;
};
atlas.set(region, buf); atlas.set(region, buf);
const offset_y: i32 = offset_y: { const offset_y: i32 = offset_y: {
@ -270,9 +281,10 @@ pub const Face = struct {
break :offset_y @intFromFloat(@ceil(baseline_with_offset)); break :offset_y @intFromFloat(@ceil(baseline_with_offset));
}; };
log.warn("FONT FONT FONT width={} height={} render_x={} render_y={} offset_y={} ascent={} cell_height={} cell_baseline={}", .{ log.warn("FONT FONT FONT rect={} width={} height={} render_x={} render_y={} offset_y={} ascent={} cell_height={} cell_baseline={}", .{
glyph_width, rect,
glyph_height, width,
height,
render_x, render_x,
render_y, render_y,
offset_y, offset_y,
@ -282,12 +294,12 @@ pub const Face = struct {
}); });
return .{ return .{
.width = glyph_width, .width = width,
.height = glyph_height, .height = height,
.offset_x = @intFromFloat(render_x), .offset_x = @intFromFloat(render_x),
.offset_y = offset_y, .offset_y = offset_y,
.atlas_x = region.x + padding, .atlas_x = region.x,
.atlas_y = region.y + padding, .atlas_y = region.y,
// This is not used, so we don't bother calculating it. If we // This is not used, so we don't bother calculating it. If we
// ever need it, we can calculate it using getAdvancesForGlyph. // ever need it, we can calculate it using getAdvancesForGlyph.