Skip to content

Commit

Permalink
Make sure we always have fonts to load even when fontkit return unrea…
Browse files Browse the repository at this point in the history
…sonable
  • Loading branch information
ctrlcctrlv committed May 10, 2023
1 parent bcd63b7 commit 91e542a
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 50 deletions.
Binary file added resources/fonts/Besley-Regular.ttf
Binary file not shown.
Binary file added resources/fonts/MFEKSans-Regular.ttf
Binary file not shown.
Binary file added resources/fonts/TT2020Base-Regular.ttf
Binary file not shown.
17 changes: 2 additions & 15 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,6 @@ pub static OFFSET_FACTOR: f32 = 10.;
pub static BIG_OFFSET_FACTOR: f32 = OFFSET_FACTOR * 10.;
pub static TINY_OFFSET_FACTOR: f32 = 1.;

// List of fonts to try in order until we find the console font.
// Warning: This is not (yet?) a fallback list. The first found font will be used for all glyphs
// for now.
use font_kit::family_name::FamilyName as FKFamilyName;
use lazy_static::lazy_static;
lazy_static! {
pub static ref CONSOLE_FONTS: Vec<FKFamilyName> = vec![
FKFamilyName::Title("Inconsolata".to_string()),
FKFamilyName::Title("Consolas".to_string()),
FKFamilyName::Title("Unifont".to_string()),
FKFamilyName::Title("Courier New".to_string()),
FKFamilyName::Monospace
];
}

/// TODO: Deprecate this hack.
/// See https://github.com/emilk/egui/issues/2639.
#[rustfmt::skip]
Expand All @@ -31,10 +16,12 @@ pub const FONT_SCALE_FACTOR: f32 = {
};

// CONSOLE
/*
pub const CONSOLE_TEXT_SIZE: f32 = 14.;
pub const CONSOLE_PADDING_X: f32 = CONSOLE_TEXT_SIZE - (CONSOLE_TEXT_SIZE / 3.);
pub const CONSOLE_PADDING_Y_TOP: f32 = 3.;
pub const CONSOLE_PADDING_Y_BOTTOM: f32 = CONSOLE_PADDING_Y_TOP / 2.;
pub static CONSOLE_FILL: u32 = 0xff_000000;
pub static CONSOLE_TEXT_FILL: u32 = 0xff_ffffff;
pub static _CONSOLE_TEXT_ERROR_FILL: u32 = 0xff_ff0000;
*/
71 changes: 36 additions & 35 deletions src/system_fonts.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use log::warn;
use lazy_static::lazy_static;

use crate::constants::CONSOLE_FONTS;

use font_kit::{
error::SelectionError::{CannotAccessSource as FKSourceError, NotFound as FKNotFoundError}, family_name::FamilyName as FKFamilyName,
error::SelectionError::{self as FKSelectionError, CannotAccessSource as FKSourceError, NotFound as FKNotFoundError}, family_name::FamilyName as FKFamilyName,
handle::Handle as FKHandle, properties::Properties, source::SystemSource,
};

Expand Down Expand Up @@ -43,27 +41,25 @@ impl TryInto<SystemFont> for FKHandle {
}
}

fn load_font(family: &[FKFamilyName]) -> SystemFont {
fn load_font(family: &[&str]) -> Result<SystemFont, FKSelectionError> {
log::debug!("Looking for a UI font to satisfy request for {:?}", family);
let source = SystemSource::new();
let props = Properties::new();
let mut font: Option<SystemFont> = None;
let mut last_err = None;
let mut best_match;
for fkfamname in family {
let best_match = source.select_best_match(&[fkfamname.clone()], &props);
best_match = source.select_by_postscript_name(&fkfamname);
if let Err(FKNotFoundError) = best_match {
log::debug!("Skipped {:?}", fkfamname);
last_err = Some(best_match.clone().unwrap_err());
}
font = match best_match {
Ok(f) => f.try_into().ok(),
// try next font…
Err(FKNotFoundError) => continue,
Err(FKSourceError) => {
let t = if let FKFamilyName::Title(t) = fkfamname {
t
} else {
"<UNKNOWN FONT>"
};
warn!("I/O error when trying to access font {}!", t);
warn!("I/O error when trying to access font {}!", fkfamname);
continue
}
};
Expand All @@ -78,17 +74,16 @@ fn load_font(family: &[FKFamilyName]) -> SystemFont {
}
}
match font {
Some(font) => font,
None => {
panic!(
"In request for {:?}, no matches were made; cannot render UI!",
family
);
}
Some(font) => Ok(font),
None => Err(last_err.unwrap())
}
}

lazy_static! {
pub static ref DEFAULTSERIF: SystemFont = (FKHandle::Memory { bytes: Arc::from(include_bytes!("../resources/fonts/Besley-Regular.ttf").to_vec()), font_index: 0 }).try_into().unwrap();
pub static ref DEFAULTSANS: SystemFont = (FKHandle::Memory { bytes: Arc::from(include_bytes!("../resources/fonts/MFEKSans-Regular.ttf").to_vec()), font_index: 0 }).try_into().unwrap();
pub static ref DEFAULTMONO: SystemFont = (FKHandle::Memory { bytes: Arc::from(include_bytes!("../resources/fonts/TT2020Base-Regular.ttf").to_vec()), font_index: 0 }).try_into().unwrap();

/// Windows 10 comes first because if we allow Windows to match on `sans-serif`, it will give
/// us Verdana, which looks incongruent on modern Windows OS. So, we specifically ask for Segoe
/// UI first. Meanwhile, on macOS…the situation is very confusing and complex due to Apple's
Expand All @@ -97,32 +92,38 @@ lazy_static! {
/// resulting in crash which became issue №220.
pub static ref SYSTEMSANS: SystemFont = load_font(&[
// Windows 10 & 11
FKFamilyName::Title("SegoeUI".to_string()),
"SegoeUI",
// Windows XP
FKFamilyName::Title("Verdana".to_string()),
"Verdana",
// Linux (fontconfig)
FKFamilyName::SansSerif,
"sans-serif",
// old macOS
FKFamilyName::Title(".SFUIText".to_string()),
".SFUIText",
// new macOS (≈2016+)
FKFamilyName::Title("Helvetica".to_string()),
"helvetica",
// Linux (fallback)
FKFamilyName::Title("Noto Sans".to_string()),
FKFamilyName::Title("Roboto".to_string()),
]);
"NotoSans-Regular",
"Roboto-Regular"
]).unwrap_or(DEFAULTSANS.clone());
pub static ref SYSTEMSERIF: SystemFont = load_font(&[
// Windows 10
FKFamilyName::Title("Times New Roman".to_string()),
"TimesNewRomanPSMT",
// Linux (fontconfig)
FKFamilyName::Serif,
"serif",
// macOS
FKFamilyName::Title("Times".to_string()),
FKFamilyName::Title("TimesNewRomanPSMT".to_string()),
"Times",
"Adobe-Times",
// Linux (fallback)
FKFamilyName::Title("FreeSerif".to_string()),
FKFamilyName::Title("Noto Serif".to_string()),
FKFamilyName::Title("Roboto Serif".to_string()),
]);
pub static ref SYSTEMMONO: SystemFont = load_font(CONSOLE_FONTS.as_slice());
"FreeSerif",
"NotoSerif-Regular",
"RobotoSerifNormalRoman_500wght",
]).unwrap_or(DEFAULTSERIF.clone());
pub static ref SYSTEMMONO: SystemFont = load_font(&[
"Inconsolata-Regular",
"Consolas",
"CourierNewPSMT",
"Adobe-Courier",
"Courier10PitchBT-Roman"
]).unwrap_or(DEFAULTMONO.clone());
pub static ref ICONSFONT: SystemFont = (FKHandle::Memory { bytes: Arc::from(include_bytes!("../resources/fonts/icons.otf").to_vec()), font_index: 0 }).try_into().unwrap();
}

0 comments on commit 91e542a

Please sign in to comment.