Draft metrics hinting support

This commit is contained in:
Héctor Ramón Jiménez 2025-11-23 06:22:24 +01:00 committed by Jeremy Soller
parent 9339446cfa
commit 48eda6bd7d
15 changed files with 41 additions and 22 deletions

View file

@ -216,6 +216,7 @@ pub struct Buffer {
wrap: Wrap,
monospace_width: Option<f32>,
tab_width: u16,
hint: bool,
}
impl Clone for Buffer {
@ -230,6 +231,7 @@ impl Clone for Buffer {
wrap: self.wrap,
monospace_width: self.monospace_width,
tab_width: self.tab_width,
hint: self.hint,
}
}
}
@ -246,7 +248,7 @@ impl Buffer {
/// # Panics
///
/// Will panic if `metrics.line_height` is zero.
pub fn new_empty(metrics: Metrics) -> Self {
pub fn new_empty(metrics: Metrics, hint: bool) -> Self {
assert_ne!(metrics.line_height, 0.0, "line height cannot be 0");
Self {
lines: Vec::new(),
@ -258,6 +260,7 @@ impl Buffer {
wrap: Wrap::WordOrGlyph,
monospace_width: None,
tab_width: 8,
hint,
}
}
@ -266,8 +269,8 @@ impl Buffer {
/// # Panics
///
/// Will panic if `metrics.line_height` is zero.
pub fn new(font_system: &mut FontSystem, metrics: Metrics) -> Self {
let mut buffer = Self::new_empty(metrics);
pub fn new(font_system: &mut FontSystem, metrics: Metrics, hint: bool) -> Self {
let mut buffer = Self::new_empty(metrics, hint);
buffer.set_text(font_system, "", &Attrs::new(), Shaping::Advanced, None);
buffer
}
@ -297,6 +300,7 @@ impl Buffer {
self.wrap,
self.monospace_width,
self.tab_width,
self.hint,
);
}
}
@ -540,6 +544,7 @@ impl Buffer {
self.wrap,
self.monospace_width,
self.tab_width,
self.hint,
))
}
@ -719,7 +724,7 @@ impl Buffer {
/// ```
/// # use cosmic_text::{Attrs, Buffer, Family, FontSystem, Metrics, Shaping};
/// # let mut font_system = FontSystem::new();
/// let mut buffer = Buffer::new_empty(Metrics::new(32.0, 44.0));
/// let mut buffer = Buffer::new_empty(Metrics::new(32.0, 44.0), false);
/// let attrs = Attrs::new().family(Family::Serif);
/// buffer.set_rich_text(
/// &mut font_system,
@ -1448,7 +1453,7 @@ impl BorrowedWithFontSystem<'_, Buffer> {
/// ```
/// # use cosmic_text::{Attrs, Buffer, Family, FontSystem, Metrics, Shaping};
/// # let mut font_system = FontSystem::new();
/// let mut buffer = Buffer::new_empty(Metrics::new(32.0, 44.0));
/// let mut buffer = Buffer::new_empty(Metrics::new(32.0, 44.0), false);
/// let attrs = Attrs::new().family(Family::Serif);
/// buffer.set_rich_text(
/// &mut font_system,

View file

@ -243,6 +243,7 @@ impl BufferLine {
wrap: Wrap,
match_mono_width: Option<f32>,
tab_width: u16,
hint: bool,
) -> &[LayoutLine] {
if self.layout_opt.is_unused() {
let align = self.align;
@ -259,6 +260,7 @@ impl BufferLine {
align,
&mut layout,
match_mono_width,
hint,
);
self.layout_opt.set_used(layout);
}

View file

@ -24,7 +24,7 @@
//! let metrics = Metrics::new(14.0, 20.0);
//!
//! // A Buffer provides shaping and layout for a UTF-8 string, create one per text widget
//! let mut buffer = Buffer::new(&mut font_system, metrics);
//! let mut buffer = Buffer::new(&mut font_system, metrics, false);
//!
//! // Borrow buffer together with the font system for more convenient method calls
//! let mut buffer = buffer.borrow_with(&mut font_system);

View file

@ -1152,6 +1152,7 @@ impl ShapeLine {
wrap: Wrap,
align: Option<Align>,
match_mono_width: Option<f32>,
hint: bool,
) -> Vec<LayoutLine> {
let mut lines = Vec::with_capacity(1);
self.layout_to_buffer(
@ -1162,6 +1163,7 @@ impl ShapeLine {
align,
&mut lines,
match_mono_width,
hint,
);
lines
}
@ -1175,6 +1177,7 @@ impl ShapeLine {
align: Option<Align>,
layout_lines: &mut Vec<LayoutLine>,
match_mono_width: Option<f32>,
hint: bool,
) {
fn add_to_visual_line(
vl: &mut VisualLine,
@ -1550,6 +1553,10 @@ impl ShapeLine {
x += alignment_correction;
}
if hint {
x = x.round();
}
// TODO: Only certain `is_whitespace` chars are typically expanded but this is what is
// currently used to compute `visual_line.spaces`.
//
@ -1628,6 +1635,9 @@ impl ShapeLine {
// Round to nearest monospace width
x_advance = ((x_advance / match_em_width).round()) * match_em_width;
}
if hint {
x_advance = x_advance.round();
}
if self.rtl {
x -= x_advance;
}