|
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