Try harder to succeed at fall-backing to a Monospace font

A combination of some ideas:

 * Try all Monospace fonts before giving up.
 * Relax exact weight restriction on font matching when trying Monospace
   fall-back. Try smaller weights if needed.
 * Make the fall-back try order weight-offset aware, AND script-aware.
 * And finally, add the option to adjust the font size of glyphs using
   fall-back Monospace fonts, so the width of them matches the default
   font width.

   For my use-case, the current fall-back attempt always fails with
   Arabic script. And none of the Arabic-supporting Monospace fonts in
   my system also support medium weight. So, if my default font is set
   to medium weight, script-aware fall-back alone will still not work.

Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
This commit is contained in:
Mohammad AlSaleh 2024-01-17 12:32:33 +03:00 committed by Jeremy Soller
parent 054b7da828
commit 329941c4a6
8 changed files with 177 additions and 39 deletions

View file

@ -232,6 +232,7 @@ pub struct Buffer {
/// True if a redraw is requires. Set to false after processing
redraw: bool,
wrap: Wrap,
monospace_width: Option<f32>,
/// Scratch buffer for shaping and laying out.
scratch: ShapeBuffer,
@ -247,6 +248,7 @@ impl Clone for Buffer {
scroll: self.scroll,
redraw: self.redraw,
wrap: self.wrap,
monospace_width: self.monospace_width,
scratch: ShapeBuffer::default(),
}
}
@ -275,6 +277,7 @@ impl Buffer {
redraw: false,
wrap: Wrap::Word,
scratch: ShapeBuffer::default(),
monospace_width: None,
}
}
@ -313,6 +316,7 @@ impl Buffer {
self.metrics.font_size,
self.width,
self.wrap,
self.monospace_width,
);
}
}
@ -492,6 +496,7 @@ impl Buffer {
self.metrics.font_size,
self.width,
self.wrap,
self.monospace_width,
))
}
@ -523,6 +528,20 @@ impl Buffer {
}
}
/// Get the current `monospace_width`
pub fn monospace_width(&self) -> Option<f32> {
self.monospace_width
}
/// Set monospace width monospace glyphs should be resized to match. `None` means don't resize
pub fn set_monospace_width(&mut self, font_system: &mut FontSystem, monospace_width: Option<f32>) {
if monospace_width != self.monospace_width {
self.monospace_width = monospace_width;
self.relayout(font_system);
self.shape_until_scroll(font_system, false);
}
}
/// Get the current buffer dimensions (width, height)
pub fn size(&self) -> (f32, f32) {
(self.width, self.height)