desktop: Load device fonts from system
This commit is contained in:
parent
7e4ac986f2
commit
2a2bcbbfbc
|
@ -49,12 +49,16 @@ impl App {
|
||||||
.build(&event_loop)?;
|
.build(&event_loop)?;
|
||||||
let window = Rc::new(window);
|
let window = Rc::new(window);
|
||||||
|
|
||||||
let mut gui = GuiController::new(window.clone(), &event_loop, &opt)?;
|
let mut font_database = fontdb::Database::default();
|
||||||
|
font_database.load_system_fonts();
|
||||||
|
|
||||||
|
let mut gui = GuiController::new(window.clone(), &event_loop, &opt, &font_database)?;
|
||||||
|
|
||||||
let mut player = PlayerController::new(
|
let mut player = PlayerController::new(
|
||||||
event_loop.create_proxy(),
|
event_loop.create_proxy(),
|
||||||
window.clone(),
|
window.clone(),
|
||||||
gui.descriptors().clone(),
|
gui.descriptors().clone(),
|
||||||
|
font_database,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(movie_url) = movie_url {
|
if let Some(movie_url) = movie_url {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use anyhow::{Context, Error};
|
use anyhow::{Context, Error};
|
||||||
use arboard::Clipboard;
|
use arboard::Clipboard;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
use fontdb::Family;
|
||||||
use rfd::{
|
use rfd::{
|
||||||
AsyncFileDialog, FileHandle, MessageButtons, MessageDialog, MessageDialogResult, MessageLevel,
|
AsyncFileDialog, FileHandle, MessageButtons, MessageDialog, MessageDialogResult, MessageLevel,
|
||||||
};
|
};
|
||||||
|
@ -120,12 +121,17 @@ pub struct DesktopUiBackend {
|
||||||
language: LanguageIdentifier,
|
language: LanguageIdentifier,
|
||||||
preferred_cursor: MouseCursor,
|
preferred_cursor: MouseCursor,
|
||||||
open_url_mode: OpenURLMode,
|
open_url_mode: OpenURLMode,
|
||||||
|
font_database: Rc<fontdb::Database>,
|
||||||
/// Is a dialog currently open
|
/// Is a dialog currently open
|
||||||
dialog_open: bool,
|
dialog_open: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DesktopUiBackend {
|
impl DesktopUiBackend {
|
||||||
pub fn new(window: Rc<Window>, open_url_mode: OpenURLMode) -> Result<Self, Error> {
|
pub fn new(
|
||||||
|
window: Rc<Window>,
|
||||||
|
open_url_mode: OpenURLMode,
|
||||||
|
font_database: Rc<fontdb::Database>,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
let preferred_language = get_locale();
|
let preferred_language = get_locale();
|
||||||
let language = preferred_language
|
let language = preferred_language
|
||||||
.and_then(|l| l.parse().ok())
|
.and_then(|l| l.parse().ok())
|
||||||
|
@ -138,6 +144,7 @@ impl DesktopUiBackend {
|
||||||
preferred_cursor: MouseCursor::Arrow,
|
preferred_cursor: MouseCursor::Arrow,
|
||||||
open_url_mode,
|
open_url_mode,
|
||||||
dialog_open: false,
|
dialog_open: false,
|
||||||
|
font_database,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,11 +256,52 @@ impl UiBackend for DesktopUiBackend {
|
||||||
|
|
||||||
fn load_device_font(
|
fn load_device_font(
|
||||||
&self,
|
&self,
|
||||||
_name: &str,
|
name: &str,
|
||||||
_is_bold: bool,
|
is_bold: bool,
|
||||||
_is_italic: bool,
|
is_italic: bool,
|
||||||
_register: &mut dyn FnMut(FontDefinition),
|
register: &mut dyn FnMut(FontDefinition),
|
||||||
) {
|
) {
|
||||||
|
let query = fontdb::Query {
|
||||||
|
families: &[Family::Name(name)],
|
||||||
|
weight: if is_bold {
|
||||||
|
fontdb::Weight::BOLD
|
||||||
|
} else {
|
||||||
|
fontdb::Weight::NORMAL
|
||||||
|
},
|
||||||
|
style: if is_italic {
|
||||||
|
fontdb::Style::Italic
|
||||||
|
} else {
|
||||||
|
fontdb::Style::Normal
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
// It'd be nice if we can get the full list of candidates... Feature request?
|
||||||
|
if let Some(id) = self.font_database.query(&query) {
|
||||||
|
if let Some(face) = self.font_database.face(id) {
|
||||||
|
tracing::info!("Loading device font \"{}\" for \"{name}\" (italic: {is_italic}, bold: {is_bold})", face.post_script_name);
|
||||||
|
|
||||||
|
match &face.source {
|
||||||
|
fontdb::Source::File(path) => match std::fs::read(path) {
|
||||||
|
Ok(bytes) => register(FontDefinition::FontFile {
|
||||||
|
name: name.to_owned(),
|
||||||
|
is_bold,
|
||||||
|
is_italic,
|
||||||
|
data: bytes,
|
||||||
|
}),
|
||||||
|
Err(e) => error!("Couldn't read font file at {path:?}: {e}"),
|
||||||
|
},
|
||||||
|
fontdb::Source::Binary(bin) | fontdb::Source::SharedFile(_, bin) => {
|
||||||
|
register(FontDefinition::FontFile {
|
||||||
|
name: name.to_owned(),
|
||||||
|
is_bold,
|
||||||
|
is_italic,
|
||||||
|
data: bin.as_ref().as_ref().to_vec(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unused on desktop
|
// Unused on desktop
|
||||||
|
|
|
@ -45,6 +45,7 @@ impl GuiController {
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
event_loop: &EventLoop<RuffleEvent>,
|
event_loop: &EventLoop<RuffleEvent>,
|
||||||
opt: &Opt,
|
opt: &Opt,
|
||||||
|
font_database: &Database,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let backend: wgpu::Backends = opt.graphics.into();
|
let backend: wgpu::Backends = opt.graphics.into();
|
||||||
if wgpu::Backends::SECONDARY.contains(backend) {
|
if wgpu::Backends::SECONDARY.contains(backend) {
|
||||||
|
@ -104,7 +105,8 @@ impl GuiController {
|
||||||
let egui_renderer = egui_wgpu::Renderer::new(&descriptors.device, surface_format, None, 1);
|
let egui_renderer = egui_wgpu::Renderer::new(&descriptors.device, surface_format, None, 1);
|
||||||
let event_loop = event_loop.create_proxy();
|
let event_loop = event_loop.create_proxy();
|
||||||
let gui = RuffleGui::new(event_loop, opt.movie_url.clone(), PlayerOptions::from(opt));
|
let gui = RuffleGui::new(event_loop, opt.movie_url.clone(), PlayerOptions::from(opt));
|
||||||
let system_fonts = load_system_fonts(gui.locale.to_owned()).unwrap_or_default();
|
let system_fonts =
|
||||||
|
load_system_fonts(font_database, gui.locale.to_owned()).unwrap_or_default();
|
||||||
egui_ctx.set_fonts(system_fonts);
|
egui_ctx.set_fonts(system_fonts);
|
||||||
|
|
||||||
egui_extras::install_image_loaders(&egui_ctx);
|
egui_extras::install_image_loaders(&egui_ctx);
|
||||||
|
@ -330,10 +332,10 @@ impl GuiController {
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to load known unicode supporting fonts to draw cjk characters in egui
|
// try to load known unicode supporting fonts to draw cjk characters in egui
|
||||||
fn load_system_fonts(locale: LanguageIdentifier) -> anyhow::Result<egui::FontDefinitions> {
|
fn load_system_fonts(
|
||||||
let mut font_database = Database::default();
|
font_database: &Database,
|
||||||
font_database.load_system_fonts();
|
locale: LanguageIdentifier,
|
||||||
|
) -> anyhow::Result<egui::FontDefinitions> {
|
||||||
let mut families = Vec::new();
|
let mut families = Vec::new();
|
||||||
if let Some(windows_font) = match locale.language.as_str() {
|
if let Some(windows_font) = match locale.language.as_str() {
|
||||||
"ja" => Some(Family::Name("MS UI Gothic")),
|
"ja" => Some(Family::Name("MS UI Gothic")),
|
||||||
|
|
|
@ -97,6 +97,7 @@ impl ActivePlayer {
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
descriptors: Arc<Descriptors>,
|
descriptors: Arc<Descriptors>,
|
||||||
movie_view: MovieView,
|
movie_view: MovieView,
|
||||||
|
font_database: Rc<fontdb::Database>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut builder = PlayerBuilder::new();
|
let mut builder = PlayerBuilder::new();
|
||||||
|
|
||||||
|
@ -152,7 +153,7 @@ impl ActivePlayer {
|
||||||
window: window.clone(),
|
window: window.clone(),
|
||||||
}))
|
}))
|
||||||
.with_ui(
|
.with_ui(
|
||||||
DesktopUiBackend::new(window.clone(), opt.open_url_mode)
|
DesktopUiBackend::new(window.clone(), opt.open_url_mode, font_database)
|
||||||
.expect("Couldn't create ui backend"),
|
.expect("Couldn't create ui backend"),
|
||||||
)
|
)
|
||||||
.with_autoplay(true)
|
.with_autoplay(true)
|
||||||
|
@ -207,6 +208,7 @@ pub struct PlayerController {
|
||||||
event_loop: EventLoopProxy<RuffleEvent>,
|
event_loop: EventLoopProxy<RuffleEvent>,
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
descriptors: Arc<Descriptors>,
|
descriptors: Arc<Descriptors>,
|
||||||
|
font_database: Rc<fontdb::Database>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlayerController {
|
impl PlayerController {
|
||||||
|
@ -214,12 +216,14 @@ impl PlayerController {
|
||||||
event_loop: EventLoopProxy<RuffleEvent>,
|
event_loop: EventLoopProxy<RuffleEvent>,
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
descriptors: Arc<Descriptors>,
|
descriptors: Arc<Descriptors>,
|
||||||
|
font_database: fontdb::Database,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
player: None,
|
player: None,
|
||||||
event_loop,
|
event_loop,
|
||||||
window,
|
window,
|
||||||
descriptors,
|
descriptors,
|
||||||
|
font_database: Rc::new(font_database),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +235,7 @@ impl PlayerController {
|
||||||
self.window.clone(),
|
self.window.clone(),
|
||||||
self.descriptors.clone(),
|
self.descriptors.clone(),
|
||||||
movie_view,
|
movie_view,
|
||||||
|
self.font_database.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue