|
1 | 1 | use super::{FontData, FontFamily, FontStyle, LayoutBox};
|
2 | 2 | use wasm_bindgen::JsCast;
|
3 |
| -use web_sys::{window, HtmlElement}; |
| 3 | +use web_sys::{window, HtmlElement, OffscreenCanvas, OffscreenCanvasRenderingContext2d}; |
4 | 4 |
|
5 | 5 | #[derive(Debug, Clone)]
|
6 | 6 | pub enum FontError {
|
@@ -29,18 +29,25 @@ impl FontData for FontDataInternal {
|
29 | 29 | ))
|
30 | 30 | }
|
31 | 31 | fn estimate_layout(&self, size: f64, text: &str) -> Result<LayoutBox, Self::ErrorType> {
|
32 |
| - let window = window().unwrap(); |
33 |
| - let document = window.document().unwrap(); |
34 |
| - let body = document.body().unwrap(); |
35 |
| - let span = document.create_element("span").unwrap(); |
36 |
| - span.set_text_content(Some(text)); |
37 |
| - span.set_attribute("style", &format!("display: inline-block; font-family:{}; font-style:{}; font-size: {}px; position: fixed; top: 100%", self.0, self.1, size)).unwrap(); |
38 |
| - let span = span.into(); |
39 |
| - body.append_with_node_1(&span).unwrap(); |
40 |
| - let elem = JsCast::dyn_into::<HtmlElement>(span).unwrap(); |
41 |
| - let height = elem.offset_height() as i32; |
42 |
| - let width = elem.offset_width() as i32; |
43 |
| - elem.remove(); |
44 |
| - Ok(((0, 0), (width, height))) |
| 32 | + let canvas = OffscreenCanvas::new(0, 0).expect("offscreen canvas"); |
| 33 | + let context = canvas |
| 34 | + .get_context("2d") |
| 35 | + .expect("getContext") |
| 36 | + .expect("context for 2d not null") |
| 37 | + .dyn_into::<OffscreenCanvasRenderingContext2d>() |
| 38 | + .expect("cast"); |
| 39 | + context.set_font("sans-serif"); |
| 40 | + context.set_font(&format!( |
| 41 | + "{} {}px {}", |
| 42 | + self.1.as_str(), |
| 43 | + size, |
| 44 | + self.0.as_str(), |
| 45 | + )); |
| 46 | + let metrics = context |
| 47 | + .measure_text(text) |
| 48 | + .expect("measure_text to return metrics"); |
| 49 | + let width = metrics.width(); |
| 50 | + let height = metrics.font_bounding_box_ascent() + metrics.font_bounding_box_descent(); |
| 51 | + Ok(((0, 0), (width as i32, height as i32))) |
45 | 52 | }
|
46 | 53 | }
|
0 commit comments