Fix problems with tabs in text (#3355)
* Move ascent out of `GlyphInfo` * Give a function a better name * Make tab and thin space act more like a normal space
This commit is contained in:
parent
fea9047abe
commit
8073ca6fe0
|
|
@ -43,12 +43,6 @@ pub struct GlyphInfo {
|
||||||
/// Unit: points.
|
/// Unit: points.
|
||||||
pub advance_width: f32,
|
pub advance_width: f32,
|
||||||
|
|
||||||
/// `ascent` value from the font metrics.
|
|
||||||
/// this is the distance from the top to the baseline.
|
|
||||||
///
|
|
||||||
/// Unit: points.
|
|
||||||
pub ascent: f32,
|
|
||||||
|
|
||||||
/// Texture coordinates.
|
/// Texture coordinates.
|
||||||
pub uv_rect: UvRect,
|
pub uv_rect: UvRect,
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +53,6 @@ impl Default for GlyphInfo {
|
||||||
Self {
|
Self {
|
||||||
id: ab_glyph::GlyphId(0),
|
id: ab_glyph::GlyphId(0),
|
||||||
advance_width: 0.0,
|
advance_width: 0.0,
|
||||||
ascent: 0.0,
|
|
||||||
uv_rect: Default::default(),
|
uv_rect: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +181,7 @@ impl FontImpl {
|
||||||
if let Some(space) = self.glyph_info(' ') {
|
if let Some(space) = self.glyph_info(' ') {
|
||||||
let glyph_info = GlyphInfo {
|
let glyph_info = GlyphInfo {
|
||||||
advance_width: crate::text::TAB_SIZE as f32 * space.advance_width,
|
advance_width: crate::text::TAB_SIZE as f32 * space.advance_width,
|
||||||
..GlyphInfo::default()
|
..space
|
||||||
};
|
};
|
||||||
self.glyph_info_cache.write().insert(c, glyph_info);
|
self.glyph_info_cache.write().insert(c, glyph_info);
|
||||||
return Some(glyph_info);
|
return Some(glyph_info);
|
||||||
|
|
@ -205,7 +198,7 @@ impl FontImpl {
|
||||||
let advance_width = f32::min(em / 6.0, space.advance_width * 0.5);
|
let advance_width = f32::min(em / 6.0, space.advance_width * 0.5);
|
||||||
let glyph_info = GlyphInfo {
|
let glyph_info = GlyphInfo {
|
||||||
advance_width,
|
advance_width,
|
||||||
..GlyphInfo::default()
|
..space
|
||||||
};
|
};
|
||||||
self.glyph_info_cache.write().insert(c, glyph_info);
|
self.glyph_info_cache.write().insert(c, glyph_info);
|
||||||
return Some(glyph_info);
|
return Some(glyph_info);
|
||||||
|
|
@ -255,6 +248,14 @@ impl FontImpl {
|
||||||
self.pixels_per_point
|
self.pixels_per_point
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is the distance from the top to the baseline.
|
||||||
|
///
|
||||||
|
/// Unit: points.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn ascent(&self) -> f32 {
|
||||||
|
self.ascent
|
||||||
|
}
|
||||||
|
|
||||||
fn allocate_glyph(&self, glyph_id: ab_glyph::GlyphId) -> GlyphInfo {
|
fn allocate_glyph(&self, glyph_id: ab_glyph::GlyphId) -> GlyphInfo {
|
||||||
assert!(glyph_id.0 != 0);
|
assert!(glyph_id.0 != 0);
|
||||||
use ab_glyph::{Font as _, ScaleFont};
|
use ab_glyph::{Font as _, ScaleFont};
|
||||||
|
|
@ -305,7 +306,6 @@ impl FontImpl {
|
||||||
GlyphInfo {
|
GlyphInfo {
|
||||||
id: glyph_id,
|
id: glyph_id,
|
||||||
advance_width: advance_width_in_points,
|
advance_width: advance_width_in_points,
|
||||||
ascent: self.ascent,
|
|
||||||
uv_rect,
|
uv_rect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -442,7 +442,7 @@ impl Font {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn glyph_info_and_font_impl(&mut self, c: char) -> (Option<&FontImpl>, GlyphInfo) {
|
pub(crate) fn font_impl_and_glyph_info(&mut self, c: char) -> (Option<&FontImpl>, GlyphInfo) {
|
||||||
if self.fonts.is_empty() {
|
if self.fonts.is_empty() {
|
||||||
return (None, self.replacement_glyph.1);
|
return (None, self.replacement_glyph.1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ fn layout_section(
|
||||||
paragraph = out_paragraphs.last_mut().unwrap();
|
paragraph = out_paragraphs.last_mut().unwrap();
|
||||||
paragraph.empty_paragraph_height = line_height; // TODO(emilk): replace this hack with actually including `\n` in the glyphs?
|
paragraph.empty_paragraph_height = line_height; // TODO(emilk): replace this hack with actually including `\n` in the glyphs?
|
||||||
} else {
|
} else {
|
||||||
let (font_impl, glyph_info) = font.glyph_info_and_font_impl(chr);
|
let (font_impl, glyph_info) = font.font_impl_and_glyph_info(chr);
|
||||||
if let Some(font_impl) = font_impl {
|
if let Some(font_impl) = font_impl {
|
||||||
if let Some(last_glyph_id) = last_glyph_id {
|
if let Some(last_glyph_id) = last_glyph_id {
|
||||||
paragraph.cursor_x += font_impl.pair_kerning(last_glyph_id, glyph_info.id);
|
paragraph.cursor_x += font_impl.pair_kerning(last_glyph_id, glyph_info.id);
|
||||||
|
|
@ -146,7 +146,7 @@ fn layout_section(
|
||||||
chr,
|
chr,
|
||||||
pos: pos2(paragraph.cursor_x, f32::NAN),
|
pos: pos2(paragraph.cursor_x, f32::NAN),
|
||||||
size: vec2(glyph_info.advance_width, line_height),
|
size: vec2(glyph_info.advance_width, line_height),
|
||||||
ascent: glyph_info.ascent,
|
ascent: font_impl.map_or(0.0, |font| font.ascent()), // Failure to find the font here would be weird
|
||||||
uv_rect: glyph_info.uv_rect,
|
uv_rect: glyph_info.uv_rect,
|
||||||
section_index,
|
section_index,
|
||||||
});
|
});
|
||||||
|
|
@ -340,12 +340,12 @@ fn replace_last_glyph_with_overflow_character(
|
||||||
.unwrap_or_else(|| font.row_height());
|
.unwrap_or_else(|| font.row_height());
|
||||||
|
|
||||||
let prev_glyph_id = prev_glyph.map(|prev_glyph| {
|
let prev_glyph_id = prev_glyph.map(|prev_glyph| {
|
||||||
let (_, prev_glyph_info) = font.glyph_info_and_font_impl(prev_glyph.chr);
|
let (_, prev_glyph_info) = font.font_impl_and_glyph_info(prev_glyph.chr);
|
||||||
prev_glyph_info.id
|
prev_glyph_info.id
|
||||||
});
|
});
|
||||||
|
|
||||||
// undo kerning with previous glyph
|
// undo kerning with previous glyph
|
||||||
let (font_impl, glyph_info) = font.glyph_info_and_font_impl(last_glyph.chr);
|
let (font_impl, glyph_info) = font.font_impl_and_glyph_info(last_glyph.chr);
|
||||||
last_glyph.pos.x -= extra_letter_spacing
|
last_glyph.pos.x -= extra_letter_spacing
|
||||||
+ font_impl
|
+ font_impl
|
||||||
.zip(prev_glyph_id)
|
.zip(prev_glyph_id)
|
||||||
|
|
@ -356,10 +356,9 @@ fn replace_last_glyph_with_overflow_character(
|
||||||
|
|
||||||
// replace the glyph
|
// replace the glyph
|
||||||
last_glyph.chr = overflow_character;
|
last_glyph.chr = overflow_character;
|
||||||
let (font_impl, glyph_info) = font.glyph_info_and_font_impl(last_glyph.chr);
|
let (font_impl, glyph_info) = font.font_impl_and_glyph_info(last_glyph.chr);
|
||||||
last_glyph.size = vec2(glyph_info.advance_width, line_height);
|
last_glyph.size = vec2(glyph_info.advance_width, line_height);
|
||||||
last_glyph.uv_rect = glyph_info.uv_rect;
|
last_glyph.uv_rect = glyph_info.uv_rect;
|
||||||
last_glyph.ascent = glyph_info.ascent;
|
|
||||||
|
|
||||||
// reapply kerning
|
// reapply kerning
|
||||||
last_glyph.pos.x += extra_letter_spacing
|
last_glyph.pos.x += extra_letter_spacing
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue