1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::os::raw::c_int;
use rich_sdl2_rust::{Result, SdlError};
use super::Font;
use crate::bind;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FontHinting {
Normal,
Light,
Mono,
None,
LightSubpixel,
}
impl FontHinting {
fn from_raw(raw: c_int) -> Self {
match raw as u32 {
bind::TTF_HINTING_NORMAL => Self::Normal,
bind::TTF_HINTING_LIGHT => Self::Light,
bind::TTF_HINTING_MONO => Self::Mono,
bind::TTF_HINTING_NONE => Self::None,
bind::TTF_HINTING_LIGHT_SUBPIXEL => Self::LightSubpixel,
_ => unreachable!(),
}
}
fn into_raw(self) -> c_int {
(match self {
Self::Normal => bind::TTF_HINTING_NORMAL,
Self::Light => bind::TTF_HINTING_LIGHT,
Self::Mono => bind::TTF_HINTING_MONO,
Self::None => bind::TTF_HINTING_NONE,
Self::LightSubpixel => bind::TTF_HINTING_LIGHT_SUBPIXEL,
}) as _
}
}
pub struct KerningDisabler<'font>(&'font Font<'font>);
impl Drop for KerningDisabler<'_> {
fn drop(&mut self) {
unsafe { bind::TTF_SetFontKerning(self.0.ptr.as_ptr(), 1) }
}
}
pub trait FontSetting {
fn hinting(&self) -> FontHinting;
fn set_hinting(&self, hinting: FontHinting);
fn disable_kerning(&self) -> KerningDisabler;
fn is_sdf(&self) -> bool;
fn set_sdf(&self, value: bool) -> Result<()>;
}
impl FontSetting for Font<'_> {
fn hinting(&self) -> FontHinting {
let raw = unsafe { bind::TTF_GetFontHinting(self.ptr.as_ptr()) };
FontHinting::from_raw(raw)
}
fn set_hinting(&self, hinting: FontHinting) {
if hinting != self.hinting() {
unsafe { bind::TTF_SetFontHinting(self.ptr.as_ptr(), hinting.into_raw()) }
}
}
fn disable_kerning(&self) -> KerningDisabler {
unsafe { bind::TTF_SetFontKerning(self.ptr.as_ptr(), 1) }
KerningDisabler(self)
}
fn is_sdf(&self) -> bool {
unsafe { bind::TTF_GetFontSDF(self.ptr.as_ptr()) == bind::SDL_bool_SDL_TRUE }
}
fn set_sdf(&self, value: bool) -> Result<()> {
if value != self.is_sdf() {
let ret = unsafe {
bind::TTF_SetFontSDF(
self.ptr.as_ptr(),
if value {
bind::SDL_bool_SDL_TRUE
} else {
bind::SDL_bool_SDL_FALSE
},
)
};
if ret == -1 {
return Err(SdlError::UnsupportedFeature);
}
}
Ok(())
}
}