skia_safe/core/
font_arguments.rs1use crate::prelude::*;
2use sb::SkFontArguments_Palette;
3use skia_bindings::{self as sb, SkFontArguments, SkFontArguments_VariationPosition};
4use std::{fmt, marker::PhantomData, mem};
5
6#[derive(Clone, Debug)]
7pub struct VariationPosition<'a> {
8 pub coordinates: &'a [variation_position::Coordinate],
9}
10
11pub mod variation_position {
12 use crate::FourByteTag;
13 use skia_bindings::SkFontArguments_VariationPosition_Coordinate;
14
15 #[derive(Copy, Clone, PartialEq, Default, Debug)]
16 #[repr(C)]
17 pub struct Coordinate {
18 pub axis: FourByteTag,
19 pub value: f32,
20 }
21
22 native_transmutable!(SkFontArguments_VariationPosition_Coordinate, Coordinate);
23}
24
25#[derive(Clone, Debug)]
26pub struct Palette<'a> {
27 pub index: i32,
28 pub overrides: &'a [palette::Override],
29}
30
31pub mod palette {
32 use crate::Color;
33 use skia_bindings::SkFontArguments_Palette_Override;
34
35 #[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
36 #[repr(C)]
37 pub struct Override {
38 pub index: u16,
39 pub color: Color,
40 }
41
42 native_transmutable!(SkFontArguments_Palette_Override, Override);
43}
44
45#[repr(C)]
46pub struct FontArguments<'vp, 'p> {
47 args: SkFontArguments,
48 pd_vp: PhantomData<&'vp [variation_position::Coordinate]>,
49 pd_p: PhantomData<&'p [palette::Override]>,
50}
51
52native_transmutable!(SkFontArguments, FontArguments<'_, '_>);
53
54impl Drop for FontArguments<'_, '_> {
55 fn drop(&mut self) {
56 unsafe { sb::C_SkFontArguments_destruct(self.native_mut()) }
57 }
58}
59
60impl Default for FontArguments<'_, '_> {
61 fn default() -> Self {
62 FontArguments::new()
63 }
64}
65
66impl fmt::Debug for FontArguments<'_, '_> {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 f.debug_struct("FontArguments")
69 .field("collection_index", &self.collection_index())
70 .field(
71 "variation_design_position",
72 &self.variation_design_position(),
73 )
74 .field("palette", &self.palette())
75 .finish()
76 }
77}
78
79impl FontArguments<'_, '_> {
80 pub fn new() -> Self {
81 Self::construct(|fa| unsafe {
82 sb::C_SkFontArguments_construct(fa);
83 })
84 }
85
86 pub fn set_collection_index(&mut self, collection_index: usize) -> &mut Self {
87 self.native_mut().fCollectionIndex = collection_index.try_into().unwrap();
88 self
89 }
90
91 pub fn set_variation_design_position(mut self, position: VariationPosition) -> FontArguments {
96 let position = SkFontArguments_VariationPosition {
97 coordinates: position.coordinates.native().as_ptr(),
98 coordinateCount: position.coordinates.len().try_into().unwrap(),
99 };
100 unsafe {
101 sb::C_SkFontArguments_setVariationDesignPosition(self.native_mut(), position);
102 mem::transmute(self)
105 }
106 }
107
108 pub fn collection_index(&self) -> usize {
109 self.native().fCollectionIndex.try_into().unwrap()
110 }
111
112 pub fn variation_design_position(&self) -> VariationPosition {
113 unsafe {
114 let position = sb::C_SkFontArguments_getVariationDesignPosition(self.native());
115 VariationPosition {
116 coordinates: safer::from_raw_parts(
117 position.coordinates as *const _,
118 position.coordinateCount.try_into().unwrap(),
119 ),
120 }
121 }
122 }
123
124 pub fn set_palette(mut self, palette: Palette) -> FontArguments {
127 let palette = SkFontArguments_Palette {
128 index: palette.index,
129 overrides: palette.overrides.native().as_ptr(),
130 overrideCount: palette.overrides.len().try_into().unwrap(),
131 };
132 unsafe {
133 sb::C_SkFontArguments_setPalette(self.native_mut(), palette);
134 mem::transmute(self)
135 }
136 }
137
138 pub fn palette(&self) -> Palette {
139 unsafe {
140 let palette = sb::C_SkFontArguments_getPalette(self.native());
141 Palette {
142 index: palette.index,
143 overrides: safer::from_raw_parts(
144 palette.overrides as *const _,
145 palette.overrideCount.try_into().unwrap(),
146 ),
147 }
148 }
149 }
150}
151
152#[test]
153fn test_font_arguments_with_no_coordinates() {
154 let fa = FontArguments::new();
155 let coordinates = fa.variation_design_position();
156 assert_eq!(coordinates.coordinates, []);
157}
158
159#[test]
160#[allow(clippy::float_cmp)]
161fn access_coordinates() {
162 let coordinates = Box::new([variation_position::Coordinate {
163 axis: 0.into(),
164 value: 1.0,
165 }]);
166 let args = FontArguments::new();
167 let pos = VariationPosition {
168 coordinates: coordinates.as_ref(),
169 };
170 let args = args.set_variation_design_position(pos);
171 assert_eq!(args.variation_design_position().coordinates[0].value, 1.0);
172 drop(args);
173}