1 | use crate::{ |
2 | prelude::*, typeface::FactoryId, Data, Drawable, FontArguments, FontMetrics, FontStyle, |
3 | GlyphId, Path, Rect, Typeface, |
4 | }; |
5 | use skia_bindings::{self as sb, SkCustomTypefaceBuilder}; |
6 | use std::fmt; |
7 | |
8 | pub type CustomTypefaceBuilder = Handle<SkCustomTypefaceBuilder>; |
9 | unsafe_send_sync!(CustomTypefaceBuilder); |
10 | |
11 | impl NativeDrop for SkCustomTypefaceBuilder { |
12 | fn drop(&mut self) { |
13 | unsafe { sb::C_SkCustomTypefaceBuilder_destruct(self) } |
14 | } |
15 | } |
16 | |
17 | impl fmt::Debug for CustomTypefaceBuilder { |
18 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
19 | f.debug_struct(name:"CustomTypefaceBuilder" ).finish() |
20 | } |
21 | } |
22 | |
23 | impl CustomTypefaceBuilder { |
24 | pub fn new() -> Self { |
25 | Self::from_native_c(unsafe { SkCustomTypefaceBuilder::new() }) |
26 | } |
27 | |
28 | pub fn set_glyph<'a>( |
29 | &mut self, |
30 | glyph_id: GlyphId, |
31 | advance: f32, |
32 | typeface_glyph: impl Into<TypefaceGlyph<'a>>, |
33 | ) -> &mut Self { |
34 | unsafe { |
35 | use TypefaceGlyph::*; |
36 | match typeface_glyph.into() { |
37 | Path(path) => self.native_mut().setGlyph(glyph_id, advance, path.native()), |
38 | DrawableAndBounds(drawable, bounds) => sb::C_SkCustomTypefaceBuilder_setGlyph( |
39 | self.native_mut(), |
40 | glyph_id, |
41 | advance, |
42 | drawable.into_ptr(), |
43 | bounds.native(), |
44 | ), |
45 | } |
46 | } |
47 | self |
48 | } |
49 | |
50 | pub fn set_metrics( |
51 | &mut self, |
52 | font_metrics: &FontMetrics, |
53 | scale: impl Into<Option<f32>>, |
54 | ) -> &mut Self { |
55 | unsafe { |
56 | self.native_mut() |
57 | .setMetrics(font_metrics.native(), scale.into().unwrap_or(1.0)) |
58 | } |
59 | self |
60 | } |
61 | |
62 | pub fn set_font_style(&mut self, font_style: FontStyle) -> &mut Self { |
63 | unsafe { self.native_mut().setFontStyle(font_style.into_native()) } |
64 | self |
65 | } |
66 | |
67 | pub fn detach(&mut self) -> Option<Typeface> { |
68 | Typeface::from_ptr(unsafe { sb::C_SkCustomTypefaceBuilder_detach(self.native_mut()) }) |
69 | } |
70 | |
71 | pub const FACTORY_ID: FactoryId = FactoryId::from_chars('u' , 's' , 'e' , 'r' ); |
72 | |
73 | // TODO: MakeFromStream |
74 | // TODO: This is a stand-in for `from_stream`. |
75 | |
76 | pub fn from_data(data: impl Into<Data>, font_arguments: &FontArguments) -> Option<Typeface> { |
77 | Typeface::from_ptr(unsafe { |
78 | sb::C_SkCustomTypefaceBuilder_FromData(data.into().into_ptr(), font_arguments.native()) |
79 | }) |
80 | } |
81 | } |
82 | |
83 | #[derive (Debug)] |
84 | pub enum TypefaceGlyph<'a> { |
85 | Path(&'a Path), |
86 | DrawableAndBounds(Drawable, Rect), |
87 | } |
88 | |
89 | impl<'a> From<&'a Path> for TypefaceGlyph<'a> { |
90 | fn from(path: &'a Path) -> Self { |
91 | Self::Path(path) |
92 | } |
93 | } |
94 | |
95 | impl From<(Drawable, Rect)> for TypefaceGlyph<'_> { |
96 | fn from((drawable: RCHandle, bounds: Rect): (Drawable, Rect)) -> Self { |
97 | Self::DrawableAndBounds(drawable, bounds) |
98 | } |
99 | } |
100 | |
101 | #[test ] |
102 | fn build_custom_typeface() { |
103 | let mut builder: Handle = CustomTypefaceBuilder::new(); |
104 | let path: Handle = Path::new(); |
105 | builder.set_glyph(glyph_id:10u16, advance:0.0, &path); |
106 | builder.set_glyph(glyph_id:11u16, advance:0.0, &path); |
107 | let typeface: RCHandle = builder.detach().unwrap(); |
108 | assert_eq!(typeface.native().ref_counted_base()._ref_cnt(), 1); |
109 | } |
110 | |