1use crate::{
24 core::{reflect::prelude::*, uuid::Uuid, TypeUuidProvider},
25 font::{Font, FontResource},
26};
27use fyrox_resource::{
28 io::ResourceIo,
29 loader::{BoxedImportOptionsLoaderFuture, BoxedLoaderFuture, LoaderPayload, ResourceLoader},
30 manager::ResourceManager,
31 options::{
32 try_get_import_settings, try_get_import_settings_opaque, BaseImportOptions, ImportOptions,
33 },
34 state::LoadError,
35};
36use serde::{Deserialize, Serialize};
37use std::{path::PathBuf, sync::Arc};
38
39fn default_page_size() -> usize {
40 1024
41}
42
43#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Reflect, Eq)]
46pub struct FontImportOptions {
47 #[serde(default = "default_page_size")]
51 pub page_size: usize,
52 pub bold: Option<FontResource>,
54 pub italic: Option<FontResource>,
56 pub bold_italic: Option<FontResource>,
58 pub fallbacks: Vec<Option<FontResource>>,
61}
62
63impl Default for FontImportOptions {
64 fn default() -> Self {
65 Self {
66 page_size: default_page_size(),
67 bold: None,
68 italic: None,
69 bold_italic: None,
70 fallbacks: Vec::default(),
71 }
72 }
73}
74
75impl ImportOptions for FontImportOptions {}
76
77pub struct FontLoader {
79 pub resource_manager: ResourceManager,
81 default_import_options: FontImportOptions,
82}
83
84impl FontLoader {
85 pub fn new(resource_manager: ResourceManager) -> Self {
87 Self {
88 resource_manager,
89 default_import_options: FontImportOptions::default(),
90 }
91 }
92}
93
94impl ResourceLoader for FontLoader {
95 fn extensions(&self) -> &[&str] {
96 &["ttf", "otf"]
97 }
98
99 fn data_type_uuid(&self) -> Uuid {
100 Font::type_uuid()
101 }
102
103 fn default_import_options(&self) -> Option<Box<dyn BaseImportOptions>> {
104 Some(Box::new(self.default_import_options.clone()))
105 }
106
107 fn try_load_import_settings(
108 &self,
109 resource_path: PathBuf,
110 io: Arc<dyn ResourceIo>,
111 ) -> BoxedImportOptionsLoaderFuture {
112 Box::pin(async move {
113 try_get_import_settings_opaque::<FontImportOptions>(&resource_path, &*io).await
114 })
115 }
116
117 fn load(&self, path: PathBuf, io: Arc<dyn ResourceIo>) -> BoxedLoaderFuture {
118 let default_import_options = self.default_import_options.clone();
119 let resource_manager = self.resource_manager.clone();
120 Box::pin(async move {
121 let io = io.as_ref();
122
123 let import_options = try_get_import_settings(&path, io)
124 .await
125 .unwrap_or(default_import_options);
126
127 let font = Font::from_file(&path, import_options, io, &resource_manager)
128 .await
129 .map_err(LoadError::new)?;
130 Ok(LoaderPayload::new(font))
131 })
132 }
133}