1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-29 16:42:13 +03:00

Add padding to glyphs in the texture atlas

I've had some reports of some artifacts in some cases and I suspect
that neighboring glyphs were to blame.
This commit is contained in:
Wez Furlong 2018-03-01 09:24:44 -08:00
parent 41f1cf9966
commit 8e68141ab1
2 changed files with 17 additions and 35 deletions

View File

@ -94,7 +94,6 @@ struct Vertex {
underline: f32,
strikethrough: f32,
v_idx: f32,
is_white: f32,
}
implement_vertex!(
@ -108,7 +107,6 @@ implement_vertex!(
underline,
strikethrough,
v_idx,
is_white,
);
const VERTEX_SHADER: &str = r#"
@ -121,7 +119,6 @@ in vec4 bg_color;
in float has_color;
in float underline;
in float v_idx;
in float is_white;
uniform mat4 projection;
uniform mat4 translation;
@ -133,7 +130,6 @@ out vec4 o_fg_color;
out vec4 o_bg_color;
out float o_has_color;
out float o_underline;
out float o_is_white;
// Offset from the RHS texture coordinate to the LHS.
// This is an underestimation to avoid the shader interpolating
@ -145,7 +141,6 @@ void main() {
o_bg_color = bg_color;
o_has_color = has_color;
o_underline = underline;
o_is_white = is_white;
if (bg_and_line_layer) {
gl_Position = projection * vec4(position, 0.0, 1.0);
@ -200,7 +195,6 @@ in vec4 o_fg_color;
in vec4 o_bg_color;
in float o_has_color;
in float o_underline;
in float o_is_white;
out vec4 color;
uniform sampler2D glyph_tex;
@ -241,8 +235,6 @@ void main() {
color = under_color;
}
}
} else if (o_is_white != 0.0) {
color = texture2D(underline_tex, tex_coords);
} else {
color = texture2D(glyph_tex, tex_coords);
if (o_has_color == 0.0) {
@ -361,13 +353,6 @@ impl Renderer {
}
}
// IMPORTANT: We also use this same texture for the whitespace cells.
// the bottom left corner MUST be a blank pixel!
assert_eq!(underline_data[0 + (width * 4 * (cell_height - 1))], 0u8);
assert_eq!(underline_data[1 + (width * 4 * (cell_height - 1))], 0u8);
assert_eq!(underline_data[2 + (width * 4 * (cell_height - 1))], 0u8);
assert_eq!(underline_data[3 + (width * 4 * (cell_height - 1))], 0u8);
glium::texture::SrgbTexture2d::new(
facade,
glium::texture::RawImage2d::from_raw_rgba(
@ -783,21 +768,11 @@ impl Renderer {
vert[V_TOP_RIGHT].has_color = has_color;
vert[V_BOT_LEFT].has_color = has_color;
vert[V_BOT_RIGHT].has_color = has_color;
vert[V_TOP_LEFT].is_white = 0.0;
vert[V_TOP_RIGHT].is_white = 0.0;
vert[V_BOT_LEFT].is_white = 0.0;
vert[V_BOT_RIGHT].is_white = 0.0;
}
&None => {
// Whitespace; no texture to render
let zero = (0.0, 0.0f32);
vert[V_TOP_LEFT].is_white = 1.0;
vert[V_TOP_RIGHT].is_white = 1.0;
vert[V_BOT_LEFT].is_white = 1.0;
vert[V_BOT_RIGHT].is_white = 1.0;
// Note: these 0 coords refer to the blank pixel
// in the bottom left of the underline texture!
vert[V_TOP_LEFT].tex = zero;
@ -852,7 +827,6 @@ impl Renderer {
vert.tex = (0.0, 0.0);
vert.adjust = Default::default();
vert.has_color = 0.0;
vert.is_white = 1.0;
}
}

View File

@ -66,14 +66,22 @@ impl Atlas {
height: u32,
data: T,
) -> Result<Sprite, OutOfTextureSpace> {
if width > self.side || height > self.side {
// We pad each sprite reservation with blank space to avoid
// surprising and unexpected artifacts when the texture is
// interpolated on to the render surface.
// In addition, we need to ensure that the bottom left pixel
// is blank as we use that for whitespace glyphs.
let reserve_width = width + 2;
let reserve_height = height + 2;
if reserve_width > self.side || reserve_height > self.side {
// It's not possible to satisfy that request
return Err(OutOfTextureSpace {
size: width.max(height).next_power_of_two(),
size: reserve_width.max(reserve_height).next_power_of_two(),
});
}
let x_left = self.side - self.left;
if x_left < width {
if x_left < reserve_width {
// Bump up to next row
self.bottom += self.tallest;
self.left = 0;
@ -82,24 +90,24 @@ impl Atlas {
// Do we have vertical space?
let y_left = self.side - self.bottom;
if y_left < height {
if y_left < reserve_height {
// No room at the inn.
return Err(OutOfTextureSpace {
size: (self.side + width.max(height)).next_power_of_two(),
size: (self.side + reserve_width.max(reserve_height)).next_power_of_two(),
});
}
let rect = Rect {
left: self.left,
bottom: self.bottom,
left: self.left + 1,
bottom: self.bottom + 1,
width,
height,
};
self.texture.write(rect, data);
self.left += width;
self.tallest = self.tallest.max(height);
self.left += reserve_width;
self.tallest = self.tallest.max(reserve_height);
Ok(Sprite {
texture: Rc::clone(&self.texture),