oxygengine_composite_renderer/
font_face_asset_protocol.rs

1use 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}