oxygengine_composite_renderer/
font_face_asset_protocol.rs1use core::{
2 assets::{
3 asset::{Asset, AssetId},
4 protocol::{AssetLoadResult, AssetProtocol, AssetVariant, Meta},
5 },
6 Ignite, Scalar,
7};
8use serde::{Deserialize, Serialize};
9use std::{any::Any, str::from_utf8};
10
11#[derive(Ignite, Debug, Clone, Serialize, Deserialize)]
12pub struct FontFace {
13 pub font: String,
14 #[serde(default)]
15 pub style: Option<String>,
16 #[serde(default = "FontFace::default_weight")]
17 pub weight: Scalar,
18 #[serde(default = "FontFace::default_stretch")]
19 pub stretch: Scalar,
20 #[serde(default)]
21 pub variant: Option<String>,
22}
23
24impl FontFace {
25 fn default_weight() -> Scalar {
26 400.0
27 }
28
29 fn default_stretch() -> Scalar {
30 100.0
31 }
32}
33
34pub struct FontFaceAsset {
35 face: FontFace,
36 font_asset: AssetId,
37}
38
39impl FontFaceAsset {
40 pub fn face(&self) -> &FontFace {
41 &self.face
42 }
43
44 pub fn font_asset(&self) -> AssetId {
45 self.font_asset
46 }
47}
48
49pub struct FontFaceAssetProtocol;
50
51impl AssetProtocol for FontFaceAssetProtocol {
52 fn name(&self) -> &str {
53 "fontface"
54 }
55
56 fn on_load(&mut self, data: Vec<u8>) -> AssetLoadResult {
57 let data = from_utf8(&data).unwrap();
58 let face: FontFace = serde_json::from_str(data).unwrap();
59 let font = face.font.clone();
60 AssetLoadResult::Yield(Some(Box::new(face)), vec![("font".to_owned(), font)])
61 }
62
63 fn on_resume(&mut self, payload: Meta, list: &[(&str, &Asset)]) -> AssetLoadResult {
64 let face = *(payload.unwrap() as Box<dyn Any + Send>)
65 .downcast::<FontFace>()
66 .unwrap();
67 let font_asset = list
68 .get(0)
69 .expect("Could not obtain font face font asset")
70 .1
71 .id();
72 AssetLoadResult::Data(Box::new(FontFaceAsset { face, font_asset }))
73 }
74
75 fn on_unload(&mut self, asset: &Asset) -> Option<Vec<AssetVariant>> {
76 asset
77 .get::<FontFaceAsset>()
78 .map(|asset| vec![AssetVariant::Id(asset.font_asset)])
79 }
80}