Fix glyph offsets in cell

We previously had a hard-coded value for aligning glyphs within cells.
The font descent is now used, and the offset should be correct by
default.
This commit is contained in:
Joe Wilm 2017-05-03 15:12:23 -07:00 committed by Joe Wilm
parent 6659810a22
commit 149fbaef09
7 changed files with 22 additions and 20 deletions

View File

@ -334,6 +334,7 @@ impl Font {
Metrics { Metrics {
average_advance: average_advance, average_advance: average_advance,
line_height: line_height, line_height: line_height,
descent: self.ct_font.descent() as f32,
} }
} }

View File

@ -64,10 +64,12 @@ impl ::Rasterize for FreeTypeRasterizer {
let width = (size_metrics.max_advance / 64) as f64; let width = (size_metrics.max_advance / 64) as f64;
let height = (size_metrics.height / 64) as f64; let height = (size_metrics.height / 64) as f64;
let descent = (size_metrics.descender / 64) as f32;
Ok(Metrics { Ok(Metrics {
average_advance: width, average_advance: width,
line_height: height, line_height: height,
descent: descent,
}) })
} }

View File

@ -219,6 +219,7 @@ impl fmt::Debug for RasterizedGlyph {
pub struct Metrics { pub struct Metrics {
pub average_advance: f64, pub average_advance: f64,
pub line_height: f64, pub line_height: f64,
pub descent: f32,
} }
pub trait Rasterize { pub trait Rasterize {

View File

@ -58,7 +58,7 @@ void main()
cellPosition.y = termDim.y - cellPosition.y - cellDim.y; cellPosition.y = termDim.y - cellPosition.y - cellDim.y;
if (backgroundPass != 0) { if (backgroundPass != 0) {
cellPosition.y = cellPosition.y - 3; cellPosition.y = cellPosition.y;
vec2 finalPosition = cellDim * position + cellPosition; vec2 finalPosition = cellDim * position + cellPosition;
gl_Position = projection * vec4(finalPosition.xy, 0.0, 1.0); gl_Position = projection * vec4(finalPosition.xy, 0.0, 1.0);
TexCoords = vec2(0, 0); TexCoords = vec2(0, 0);

View File

@ -177,8 +177,8 @@ impl Display {
// Resize window to specified dimensions // Resize window to specified dimensions
let dimensions = options.dimensions() let dimensions = options.dimensions()
.unwrap_or_else(|| config.dimensions()); .unwrap_or_else(|| config.dimensions());
let width = cell_width * dimensions.columns_u32() + 4; let width = cell_width * dimensions.columns_u32();
let height = cell_height * dimensions.lines_u32() + 4; let height = cell_height * dimensions.lines_u32();
let size = Size { width: Pixels(width), height: Pixels(height) }; let size = Size { width: Pixels(width), height: Pixels(height) };
info!("set_inner_size: {}", size); info!("set_inner_size: {}", size);

View File

@ -157,6 +157,8 @@ pub struct GlyphCache {
/// glyph offset /// glyph offset
glyph_offset: Delta, glyph_offset: Delta,
metrics: ::font::Metrics,
} }
impl GlyphCache { impl GlyphCache {
@ -220,6 +222,12 @@ impl GlyphCache {
.unwrap_or_else(|_| regular) .unwrap_or_else(|_| regular)
}; };
// Need to load at least one glyph for the face before calling metrics.
// The glyph requested here ('m' at the time of writing) has no special
// meaning.
rasterizer.get_glyph(&GlyphKey { font_key: regular, c: 'm' as char, size: font.size() })?;
let metrics = rasterizer.metrics(regular)?;
let mut cache = GlyphCache { let mut cache = GlyphCache {
cache: HashMap::default(), cache: HashMap::default(),
rasterizer: rasterizer, rasterizer: rasterizer,
@ -228,12 +236,13 @@ impl GlyphCache {
bold_key: bold, bold_key: bold,
italic_key: italic, italic_key: italic,
glyph_offset: glyph_offset, glyph_offset: glyph_offset,
metrics: metrics
}; };
macro_rules! load_glyphs_for_font { macro_rules! load_glyphs_for_font {
($font:expr) => { ($font:expr) => {
for i in RangeInclusive::new(32u8, 128u8) { for i in RangeInclusive::new(32u8, 128u8) {
cache.load_and_cache_glyph(GlyphKey { cache.get(&GlyphKey {
font_key: $font, font_key: $font,
c: i as char, c: i as char,
size: font.size() size: font.size()
@ -255,33 +264,22 @@ impl GlyphCache {
.expect("metrics load since font is loaded at glyph cache creation") .expect("metrics load since font is loaded at glyph cache creation")
} }
fn load_and_cache_glyph<L>(&mut self, glyph_key: GlyphKey, loader: &mut L)
where L: LoadGlyph
{
let mut rasterized = self.rasterizer.get_glyph(&glyph_key)
.unwrap_or_else(|_| Default::default());
rasterized.left += self.glyph_offset.x as i32;
rasterized.top += self.glyph_offset.y as i32;
let glyph = loader.load_glyph(&rasterized);
self.cache.insert(glyph_key, glyph);
}
pub fn get<'a, L>(&'a mut self, glyph_key: &GlyphKey, loader: &mut L) -> &'a Glyph pub fn get<'a, L>(&'a mut self, glyph_key: &GlyphKey, loader: &mut L) -> &'a Glyph
where L: LoadGlyph where L: LoadGlyph
{ {
let glyph_offset = self.glyph_offset; let glyph_offset = self.glyph_offset;
let rasterizer = &mut self.rasterizer; let rasterizer = &mut self.rasterizer;
let metrics = &self.metrics;
self.cache self.cache
.entry(*glyph_key) .entry(*glyph_key)
.or_insert_with(|| { .or_insert_with(|| {
let mut rasterized = rasterizer.get_glyph(&glyph_key) let mut rasterized = rasterizer.get_glyph(&glyph_key)
.unwrap_or_else(|_| Default::default()); .unwrap_or_else(|_| Default::default());
// We need to apply the offset to glyphs that didn't get cached initially // Apply offsets so they aren't computed every draw
rasterized.left += glyph_offset.x as i32; rasterized.left += glyph_offset.x as i32;
rasterized.top += glyph_offset.y as i32; rasterized.top += glyph_offset.y as i32;
rasterized.top -= metrics.descent as i32;
loader.load_glyph(&rasterized) loader.load_glyph(&rasterized)
}) })

View File

@ -556,12 +556,12 @@ pub struct SizeInfo {
impl SizeInfo { impl SizeInfo {
#[inline] #[inline]
pub fn lines(&self) -> Line { pub fn lines(&self) -> Line {
Line((self.height / self.cell_height) as usize) Line(((self.height - 4.0) / self.cell_height) as usize)
} }
#[inline] #[inline]
pub fn cols(&self) -> Column { pub fn cols(&self) -> Column {
Column((self.width / self.cell_width) as usize) Column(((self.width - 4.0) / self.cell_width) as usize)
} }
pub fn pixels_to_coords(&self, x: usize, y: usize) -> Option<Point> { pub fn pixels_to_coords(&self, x: usize, y: usize) -> Option<Point> {