Skip to content

Commit

Permalink
Load system fonts
Browse files Browse the repository at this point in the history
  • Loading branch information
ctrlcctrlv committed Mar 13, 2023
1 parent bd588ab commit 5ca548f
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 14 deletions.
8 changes: 8 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ fn main() {
warning!("It is neither recommended nor supported to compile MFEKglif on Windows w/dynamic SDL2.");
}
}
cfg_if! {
if #[cfg(all(target_family = "unix", not(any(target_os = "macos", target_os = "android", target_os = "ios"))))] {
rustc_cfg!("is_free_software_os");
rustc_env!("MFEK_FREE_OS_DETECTED", "{}", version);
} else {
warning!("MFEKglif works best on free software operating systems such as GNU/Linux and FreeBSD. Close Windows, open doors: <https://www.fsf.org/windows>");
}
}
}

#[cfg(all(target_os = "macos", feature = "sdl2-dynamic"))]
Expand Down
11 changes: 11 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@ 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.
pub const FONT_SCALE_FACTOR: f32 = {
#[cfg(is_free_software_os)]
{ 1.25 }
#[cfg(not(is_free_software_os))]
{ 1.0 }
};

// CONSOLE
pub const CONSOLE_TEXT_SIZE: f32 = 14.;
pub const CONSOLE_PADDING_X: f32 = CONSOLE_TEXT_SIZE - (CONSOLE_TEXT_SIZE / 3.);
Expand Down
46 changes: 36 additions & 10 deletions src/system_fonts.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use lazy_static::lazy_static;

//use crate::constants::CONSOLE_FONTS;
use crate::constants::CONSOLE_FONTS;

use font_kit::{
error::SelectionError::NotFound as FKNotFoundError, family_name::FamilyName as FKFamilyName,
Expand All @@ -11,12 +11,13 @@ use std::fs;
use std::path::PathBuf;
use std::sync::Arc;

pub struct Font {
#[derive(Clone, Debug)]
pub struct SystemFont {
pub data: Vec<u8>,
pub path: Option<PathBuf>,
}

fn load_font(family: &[FKFamilyName]) -> Font {
fn load_font(family: &[FKFamilyName]) -> SystemFont {
log::debug!("Looking for a UI font to satisfy request for {:?}", family);
let mut font = None;
let source = SystemSource::new();
Expand All @@ -27,11 +28,20 @@ fn load_font(family: &[FKFamilyName]) -> Font {
log::debug!("Skipped {:?}", fkfamname);
}
font = match best_match {
Ok(FKHandle::Path { path, .. }) => Some(Font {
path: Some(path.clone()),
data: fs::read(path).expect("Failed to open font path system specified"),
}),
Ok(FKHandle::Memory { bytes, .. }) => Some(Font {
Ok(FKHandle::Path { path, .. }) => {
let font_is_scalable = ["otf", "ttf"]
.into_iter()
.any(|e: &str| path.extension().map(|ee| ee == e).unwrap_or(false));
// This is possible on GNU/Linux which has BDF fonts.
if !font_is_scalable {
continue;
}
Some(SystemFont {
path: Some(path.clone()),
data: fs::read(path).expect("Failed to open font path system specified"),
})
}
Ok(FKHandle::Memory { bytes, .. }) => Some(SystemFont {
path: None,
data: Arc::try_unwrap(bytes).expect("Failed to load in-memory font"),
}),
Expand Down Expand Up @@ -70,7 +80,7 @@ lazy_static! {
/// difficulty in deciding on a default font. I believe it works to try "Helvetica" and then
/// ".SFUI-Text" (San Francisco UI Text); Apple does _NOT_ resolve `sans-serif` to anything,
/// resulting in crash which became issue №220.
pub static ref SYSTEMSANS: Font = load_font(&[
pub static ref SYSTEMSANS: SystemFont = load_font(&[
// Windows 10
FKFamilyName::Title("Segoe UI".to_string()),
// Linux (fontconfig)
Expand All @@ -79,6 +89,22 @@ lazy_static! {
FKFamilyName::Title(".SFUIText".to_string()),
// new macOS (≈2016+)
FKFamilyName::Title("Helvetica".to_string()),
// Linux (fallback)
FKFamilyName::Title("Noto Sans".to_string()),
FKFamilyName::Title("Roboto".to_string()),
]);
pub static ref SYSTEMSERIF: SystemFont = load_font(&[
// Windows 10
FKFamilyName::Title("Times New Roman".to_string()),
// Linux (fontconfig)
FKFamilyName::Serif,
// macOS
FKFamilyName::Title("Times".to_string()),
FKFamilyName::Title("TimesNewRomanPSMT".to_string()),
// Linux (fallback)
FKFamilyName::Title("FreeSerif".to_string()),
FKFamilyName::Title("Noto Serif".to_string()),
FKFamilyName::Title("Roboto Serif".to_string()),
]);
//pub static ref SYSTEMMONO: Font = load_font(CONSOLE_FONTS.as_slice());
pub static ref SYSTEMMONO: SystemFont = load_font(CONSOLE_FONTS.as_slice());
}
24 changes: 24 additions & 0 deletions src/user_interface/egui_manager/fonts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use super::EguiManager;

use egui::{FontData, FontDefinitions, FontTweak};

use crate::constants;
use crate::system_fonts::*;

fn tweak(font: FontData) -> FontData {
font.tweak(FontTweak {scale: constants::FONT_SCALE_FACTOR, .. Default::default()})
}

impl EguiManager {
pub fn set_system_fonts(&mut self) {
let ctx = &self.egui.egui_ctx;
let mut fonts = egui::FontDefinitions::default();
fonts.font_data.iter_mut().map(move |s|{let new = tweak((s.1).clone()); *s.1 = new;}).for_each(drop);
fonts.font_data.insert("sans".to_owned(), tweak(egui::FontData::from_static(&SYSTEMSANS.data)));
fonts.font_data.insert("serif".to_owned(), tweak(egui::FontData::from_static(&SYSTEMSERIF.data)));
fonts.font_data.insert("mono".to_owned(), tweak(egui::FontData::from_static(&SYSTEMMONO.data)));
fonts.families.get_mut(&egui::FontFamily::Proportional).unwrap().insert(0, "sans".to_owned());
fonts.families.get_mut(&egui::FontFamily::Monospace).unwrap().insert(0, "mono".to_owned());
ctx.set_fonts(fonts);
}
}
6 changes: 6 additions & 0 deletions src/user_interface/egui_manager/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod fonts;

use egui_skia::EguiSkia;
use sdl2::{event::Event, video::Window};

Expand Down Expand Up @@ -25,6 +27,10 @@ impl EguiManager {
};
}

pub fn init(&mut self) {
self.set_system_fonts();
}

pub fn wants_event(&mut self, sdl_window: &Window, sdl_event: &Event) -> bool {
self.egui_sdl2.sdl2_input_to_egui(sdl_window, sdl_event);

Expand Down
2 changes: 2 additions & 0 deletions src/user_interface/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub fn build_ui(
i: &mut Interface,
wm: &mut WindowManager,
) {
// initialization (so far just sets fonts to system fonts not included Ubuntu)
egui_manager.init();
let egui = &mut egui_manager.egui;
let egsdl2 = &mut egui_manager.egui_sdl2;
egui.run(egsdl2.take_egui_input(&i.sdl_window), |ctx| {
Expand Down
8 changes: 4 additions & 4 deletions src/user_interface/gui/tool_bar.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use egui::{Align2, Color32, Context, Stroke, Ui};

use crate::{editor::Editor, tools::ToolEnum, user_interface::Interface};
use crate::{constants::*, editor::Editor, tools::ToolEnum, user_interface::Interface};

pub fn build_button(v: &mut Editor, ui: &mut Ui, text: &str, te: ToolEnum) {
let stroke = if v.get_tool() == te {
Expand All @@ -25,10 +25,10 @@ pub fn build_button(v: &mut Editor, ui: &mut Ui, text: &str, te: ToolEnum) {
}
pub fn tool_bar(ctx: &Context, v: &mut Editor, _i: &mut Interface) {
egui::Window::new("Tools")
.anchor(Align2::LEFT_TOP, [0., 25.])
.anchor(Align2::LEFT_TOP, [0., 25. * FONT_SCALE_FACTOR])
.title_bar(false)
.default_width(10.)
.min_width(15.)
.default_width(10. * FONT_SCALE_FACTOR)
.min_width(15. * FONT_SCALE_FACTOR)
.resizable(false)
.enabled(!v.is_modifying())
.show(ctx, |ui| {
Expand Down

0 comments on commit 5ca548f

Please sign in to comment.