1use crate::{
2 prelude::*, typeface::FactoryId, Data, Drawable, FontArguments, FontMetrics, FontStyle,
3 GlyphId, Path, Rect, Typeface,
4};
5use skia_bindings::{self as sb, SkCustomTypefaceBuilder};
6use std::fmt;
7
8pub type CustomTypefaceBuilder = Handle<SkCustomTypefaceBuilder>;
9unsafe_send_sync!(CustomTypefaceBuilder);
10
11impl NativeDrop for SkCustomTypefaceBuilder {
12 fn drop(&mut self) {
13 unsafe { sb::C_SkCustomTypefaceBuilder_destruct(self) }
14 }
15}
16
17impl fmt::Debug for CustomTypefaceBuilder {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 f.debug_struct(name:"CustomTypefaceBuilder").finish()
20 }
21}
22
23impl 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)]
84pub enum TypefaceGlyph<'a> {
85 Path(&'a Path),
86 DrawableAndBounds(Drawable, Rect),
87}
88
89impl<'a> From<&'a Path> for TypefaceGlyph<'a> {
90 fn from(path: &'a Path) -> Self {
91 Self::Path(path)
92 }
93}
94
95impl 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]
102fn 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