wasm_game_lib/graphics/
font.rs

1use futures::channel::oneshot::Sender;
2use wasm_bindgen::JsValue;
3
4/// This struct represent a font.
5/// It is useful when using the [Text struct](../text/struct.Text.html).
6/// 
7/// # Example
8/// 
9/// ```rust
10/// use wasm_game_lib::graphics::font::Font;
11/// use wasm_game_lib::graphics::text::Text;
12/// 
13/// # async fn test() {
14/// // use a default font
15/// let arial = Font::arial();
16/// 
17/// // load a custom font
18/// let trade_winds = Font::load("https://fonts.gstatic.com/s/tradewinds/v8/AYCPpXPpYNIIT7h8-QenM0Jt5vM.woff2").await.unwrap();
19/// 
20/// // use the fonts with the Text struct
21/// let arial_text = Text::new_with_text_and_coords(&arial, String::from("This text is using Arial font."), (0,100));
22/// let trade_winds_text = Text::new_with_text_and_coords(&trade_winds, String::from("This text is using Trade Winds font."), (0,200));
23/// # }
24/// ```
25#[derive(Debug)]
26pub struct Font {
27    pub(crate) name: String
28}
29
30impl Font {
31    /// Load a custom font from an url.
32    /// The load may fail so a Result is returned.
33    /// 
34    /// # Example
35    /// 
36    /// ```rust
37    /// use wasm_game_lib::graphics::font::Font;
38    /// use wasm_game_lib::graphics::text::Text;
39    /// 
40    /// # async fn test() {
41    /// // load the font
42    /// let trade_winds = Font::load("https://fonts.gstatic.com/s/tradewinds/v8/AYCPpXPpYNIIT7h8-QenM0Jt5vM.woff2").await.unwrap();
43    /// 
44    /// // use the font with the Text struct
45    /// let trade_winds_text = Text::new_with_text_and_coords(&trade_winds, String::from("This text is using Trade Winds font."), (0,100));
46    /// # }
47    /// ```
48    /// 
49    /// # About Google Fonts
50    /// 
51    /// If you are using google fonts, you may have a link like "https://fonts.googleapis.com/css?family=Trade+Winds&display=swap".
52    /// To get the font url from this link, load this link in a web browser. 
53    /// You should get something like that:
54    /// ```text
55    /// /* latin */
56    /// @font-face {
57    ///     font-family: 'Trade Winds';
58    ///     font-style: normal;
59    ///     font-weight: 400;
60    ///     font-display: swap;
61    ///     src: local('Trade Winds'), local('TradeWinds'), url(https://fonts.gstatic.com/s/tradewinds/v8/AYCPpXPpYNIIT7h8-QenM0Jt5vM.woff2) format('woff2');
62    ///     unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
63    /// }
64    /// ```
65    /// The url of the font is located at the seventh line, after "url(".
66    pub async fn load(url: &str) -> Result<Font, JsValue> {
67        use web_sys::FontFace;
68        use web_sys::window;
69        use wasm_bindgen_futures::JsFuture;
70
71        let window = window().unwrap();
72
73        let crypto = window.crypto()?;
74        let mut randoms = [0; 25];
75        crypto.get_random_values_with_u8_array(&mut randoms)?;
76        let mut family_name = String::new();
77        for random in randoms.iter() {
78            family_name.push(match random % 26 {
79                0 => 'a',
80                1 => 'b',
81                2 => 'c',
82                3 => 'd',
83                4 => 'e',
84                5 => 'f',
85                6 => 'g',
86                7 => 'h',
87                8 => 'i',
88                9 => 'j',
89                10 => 'k',
90                11 => 'l',
91                12 => 'm',
92                13 => 'n',
93                14 => 'o',
94                15 => 'p',
95                16 => 'q',
96                17 => 'r',
97                18 => 's',
98                19 => 't',
99                20 => 'u',
100                21 => 'v',
101                22 => 'w',
102                23 => 'x',
103                24 => 'y',
104                _ => 'z'
105            });
106        }
107        let font = FontFace::new_with_str(&family_name, &format!("url({})", url))?;
108        JsFuture::from(font.load()?).await?;
109
110        window.document().unwrap().fonts().add(&font)?;
111
112        Ok(Font {
113            name: family_name
114        })
115    }
116
117    /// Load a custom font from an url  and send it trought a [oneshot channel](https://docs.rs/futures/0.3.4/futures/channel/oneshot/fn.channel.html).
118    /// 
119    /// It works exactly like [images](../image/struct.Image.html#method.load_and_send) so see that for an example.
120    pub async fn load_and_send(url: &str, sender: Sender<Result<Font, JsValue>>) {
121        let font = Font::load(url).await;
122        sender.send(font).expect("can't send the loaded font trought the oneshot shannel");
123    }
124
125    /// Return the Sherif font.
126    pub fn sherif() -> Font {
127        Font {
128            name: String::from("sherif"),
129        }
130    }
131
132    /// Return the Arial font.
133    pub fn arial() -> Font {
134        Font {
135            name: String::from("Arial"),
136        }
137    }
138
139    /// Return the Times New Roman font.
140    pub fn times_new_roman() -> Font {
141        Font {
142            name: String::from("Times New Roman"),
143        }
144    }
145
146    /// Return the Times font.
147    pub fn times() -> Font {
148        Font {
149            name: String::from("Times"),
150        }
151    }
152
153    /// Return the Courier New font.
154    pub fn courier_new() -> Font {
155        Font {
156            name: String::from("Courier New"),
157        }
158    }
159
160    /// Return the Courier font.
161    pub fn courier() -> Font {
162        Font {
163            name: String::from("Courier"),
164        }
165    }
166
167    /// Return the Verdana font.
168    pub fn verdana() -> Font {
169        Font {
170            name: String::from("Verdana"),
171        }
172    }
173
174    /// Return the Georgia font.
175    pub fn georgia() -> Font {
176        Font {
177            name: String::from("Georgia"),
178        }
179    }
180
181    /// Return the Palatino font.
182    pub fn palatino() -> Font {
183        Font {
184            name: String::from("Palatino"),
185        }
186    }
187
188    /// Return the Garamond font.
189    pub fn garamond() -> Font {
190        Font {
191            name: String::from("Garamond"),
192        }
193    }
194
195    /// Return the Bookman font.
196    pub fn bookman() -> Font {
197        Font {
198            name: String::from("Bookman"),
199        }
200    }
201
202    /// Return the Comic Sans Ms font.
203    pub fn comic_sans_ms() -> Font {
204        Font {
205            name: String::from("Comic Sans MS"),
206        }
207    }
208
209    /// Return the Candara font.
210    pub fn candara() -> Font {
211        Font {
212            name: String::from("Candara"),
213        }
214    }
215
216    /// Return the Helvetica font.
217    pub fn helvetica() -> Font {
218        Font {
219            name: String::from("Helvetica"),
220        }
221    }
222
223    /// Return the Arial Black font.
224    pub fn arial_black() -> Font {
225        Font {
226            name: String::from("Arial Black"),
227        }
228    }
229
230    /// Return the Inpact font.
231    pub fn impact() -> Font {
232        Font {
233            name: String::from("Impact"),
234        }
235    }
236}