Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] }
webbrowser = { version = "1.0.4", optional = true }
zip = { version = "7.2.0", features = ["deflate-flate2"], default-features = false }

[target.'cfg(target_os = "linux")'.dependencies]
fontconfig = { version = "0.10.0", optional = true }

[features]
default = ["gui"]

gui = ["dep:eframe", "dep:egui", "dep:rfd", "dep:webbrowser", "dep:rand", "dep:current_locale"]
gui = ["dep:eframe", "dep:egui", "dep:rfd", "dep:webbrowser", "dep:rand", "dep:current_locale", "dep:fontconfig"]

[build-dependencies]
embed-resource = "3.0.5"
Expand Down
56 changes: 56 additions & 0 deletions res/font/fonts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"windows": {
"zh-CN": [
"msyh.ttc",
"msyhbd.ttc",
"simsun.ttc",
"simhei.ttf",
"simkai.ttf",
"simfang.ttf",
"msjh.ttc",
"msjhbd.ttc"
],
"ja": [
"meiryo.ttc",
"meiryob.ttc",
"msgothic.ttc",
"msmincho.ttc",
"YuGothM.ttc",
"YuGothB.ttc",
"YuMincho.ttc"
]
},
"linux": {
"zh-CN": [
"Noto Sans CJK SC",
"WenQuanYi Micro Hei",
"WenQuanYi Zen Hei",
"AR PL UMing CN",
"AR PL UKai CN"
],
"ja": [
"Noto Sans CJK JP",
"Noto Sans CJK SC",
"Noto Sans CJK TC",
"Noto Sans JP",
"IPAGothic",
"IPA Gothic",
"VL Gothic"
]
},
"macos": {
"zh-CN": [
"PingFang.ttc",
"STHeiti Light.ttc",
"STHeiti Medium.ttc",
"Hiragino Sans GB.ttc",
"Arial Unicode.ttf"
],
"ja": [
"ヒラギノ角ゴシック W3.ttc",
"ヒラギノ明朝 ProN.ttc",
"ヒラギノ丸ゴ ProN W4.ttc",
"Hiragino Sans GB.ttc"
]
}
}
132 changes: 132 additions & 0 deletions src/ui/font_loader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use egui::FontData;
use egui::FontFamily::{Monospace, Proportional};
use egui::epaint::text::FontPriority::Lowest;
use egui::epaint::text::{FontInsert, InsertFontFamily};
use serde::Deserialize;
use std::collections::HashMap;
use log::warn;

const FONT_LIST: &str = include_str!("../../res/font/fonts.json");

#[cfg(target_os = "windows")]
const WINDOWS_FONT_PATH: &str = r"C:\Windows\Fonts\";
#[cfg(target_os = "macos")]
const MACOS_FONT_PATH: &str = "/System/Library/Fonts/";
#[cfg(target_os = "macos")]
const MACOS_FONT_PATH_SHARED: &str = "/Library/Fonts/";

#[derive(Deserialize)]
struct SystemFontList {
#[cfg(target_os = "windows")]
windows: PlatformFonts,
#[cfg(target_os = "linux")]
linux: PlatformFonts,
#[cfg(target_os = "macos")]
macos: PlatformFonts,
}

type PlatformFonts = HashMap<String, Vec<String>>;

pub fn load_system_font_to_egui(ctx: &egui::Context) {
let system_font = find_system_font();

if system_font.is_empty() {
warn!("No system font found, some languages may not display properly.");
return;
}

for font in system_font {
let font_insert = FontInsert::new(
&font.0,
font.1,
vec![
InsertFontFamily {
family: Proportional,
priority: Lowest, // low priority to not override existing fonts
},
InsertFontFamily {
family: Monospace,
priority: Lowest,
},
],
);

ctx.add_font(font_insert);
}
}

fn find_system_font() -> HashMap<String, FontData> {
let sys_font_list: SystemFontList =
serde_json::from_str(FONT_LIST).expect("failed to parse font list");

let mut result: HashMap<String, FontData> = HashMap::new();

#[cfg(target_os = "windows")]
{
load_fonts_from_paths(&sys_font_list.windows, &[WINDOWS_FONT_PATH], &mut result);
}

#[cfg(target_os = "macos")]
{
load_fonts_from_paths(
&sys_font_list.macos,
&[MACOS_FONT_PATH, MACOS_FONT_PATH_SHARED],
&mut result,
);
}

#[cfg(target_os = "linux")]
{
// use fontconfig for linux fo find fonts
load_fonts_from_fontconfig(&sys_font_list.linux, &mut result);
}

result
}

#[cfg(any(target_os = "windows", target_os = "macos"))]
fn load_fonts_from_paths(
platform_fonts: &PlatformFonts,
search_paths: &[&str],
result: &mut HashMap<String, FontData>,
) {
for (language, font_files) in platform_fonts {
let mut loaded = false;
for font_file in font_files {
for search_path in search_paths {
let font_path = format!("{}{}", search_path, font_file);
if let Ok(font_data) = std::fs::read(&font_path) {
result.insert(language.to_string(), FontData::from_owned(font_data));
loaded = true;
break;
}
}
if loaded {
break;
}
}
}
}

#[cfg(all(target_os = "linux", feature = "gui"))]
fn load_fonts_from_fontconfig(
platform_fonts: &PlatformFonts,
result: &mut HashMap<String, FontData>,
) {
use fontconfig::Fontconfig;

if let Some(fc) = Fontconfig::new() {
platform_fonts.iter().for_each(|(language, font_names)| {
for font_name in font_names {
if let Some(font) = fc.find(font_name, None) {
if let Ok(data) = std::fs::read(font.path) {
result.insert(language.to_string(), FontData::from_owned(data));
break;
}
}
}
})
} else {
warn!("Failed to init Fontconfig")
}
}
9 changes: 8 additions & 1 deletion src/ui/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ use egui::{
};
use std::hash::Hash;

use crate::ui::font_loader::load_system_font_to_egui;

#[derive(PartialEq, Clone, Copy, Debug)]
enum Mode {
Client,
Expand Down Expand Up @@ -80,7 +82,12 @@ async fn create_window() -> Result<(), InstallerError> {
eframe::run_native(
&("Ornithe Installer ".to_owned() + crate::VERSION),
options,
Box::new(|_cc| Ok(Box::new(app))),
Box::new(|_cc| {
// load needed system fonts
load_system_font_to_egui(&_cc.egui_ctx);

Ok(Box::new(app))
}),
)?;
Ok(())
}
Expand Down
3 changes: 3 additions & 0 deletions src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ pub mod cli;
#[cfg(feature = "gui")]
pub mod gui;

#[cfg(feature = "gui")]
mod font_loader;

fn home_dir() -> Option<PathBuf> {
#[allow(deprecated)]
std::env::home_dir()
Expand Down