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}