Skip to content

Commit c242701

Browse files
authored
Prevent users from creating Sdl2TtfContext out of nothing and use SDL's reference counting init/quit (#1437)
* prevent users from creating `Sdl2TtfContext` out of nothing and various other changes, including: - allow multiple `ttf::init` calls, the same way it works with TTF_Init - return last sdl error instead of I/O error (like stale pr #1348, fixes #1347 and closes #1348) - implement `Clone` for `Sdl2TtfContext`, SDL C code will do the reference counting - make `ttf::font::internal_*` `pub(super)` - make `ttf::font::Font::raw` safe (obtaining a raw pointer is safe, using it is unsafe) * remove `InitError` because only one variant was used * update changelog
1 parent 863399d commit c242701

File tree

4 files changed

+31
-49
lines changed

4 files changed

+31
-49
lines changed

changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ when upgrading from a version of rust-sdl2 to another.
33

44
### Next
55

6+
[PR #1437](https://github.com/Rust-SDL2/rust-sdl2/pull/1437) **BREAKING CHANGE** Prevent users from creating `Sdl2TtfContext` out of nothing and use SDL's reference counting init/quit
7+
68
[PR #1464](https://github.com/Rust-SDL2/rust-sdl2/pull/1464) Added binding for `Mix_OpenAudioDevice`
79

810
[PR #1451](https://github.com/Rust-SDL2/rust-sdl2/pull/1451) Add `gamma_ramp_arrays` and `calculate_gamma_ramp`.

src/sdl2/ttf/context.rs

+22-43
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use get_error;
22
use rwops::RWops;
33
use std::error;
44
use std::fmt;
5-
use std::io;
65
use std::os::raw::{c_int, c_long};
76
use std::path::Path;
87
use sys::ttf;
@@ -14,7 +13,14 @@ use super::font::{
1413

1514
/// A context manager for `SDL2_TTF` to manage C code initialization and clean-up.
1615
#[must_use]
17-
pub struct Sdl2TtfContext;
16+
pub struct Sdl2TtfContext(());
17+
18+
impl Clone for Sdl2TtfContext {
19+
fn clone(&self) -> Self {
20+
// This should not return an error because SDL_ttf is already initialized
21+
init().unwrap()
22+
}
23+
}
1824

1925
// Clean up the context once it goes out of scope
2026
impl Drop for Sdl2TtfContext {
@@ -54,7 +60,7 @@ impl Sdl2TtfContext {
5460
point_size: u16,
5561
) -> Result<Font<'ttf, 'r>, String> {
5662
let raw = unsafe { ttf::TTF_OpenFontRW(rwops.raw(), 0, point_size as c_int) };
57-
if (raw as *mut ()).is_null() {
63+
if raw.is_null() {
5864
Err(get_error())
5965
} else {
6066
Ok(internal_load_font_from_ll(raw, Some(rwops)))
@@ -72,7 +78,7 @@ impl Sdl2TtfContext {
7278
let raw = unsafe {
7379
ttf::TTF_OpenFontIndexRW(rwops.raw(), 0, point_size as c_int, index as c_long)
7480
};
75-
if (raw as *mut ()).is_null() {
81+
if raw.is_null() {
7682
Err(get_error())
7783
} else {
7884
Ok(internal_load_font_from_ll(raw, Some(rwops)))
@@ -82,52 +88,25 @@ impl Sdl2TtfContext {
8288

8389
/// Returns the version of the dynamically linked `SDL_TTF` library
8490
pub fn get_linked_version() -> Version {
85-
unsafe { Version::from_ll(*ttf::TTF_Linked_Version()) }
86-
}
87-
88-
/// An error for when `sdl2_ttf` is attempted initialized twice
89-
/// Necessary for context management, unless we find a way to have a singleton
90-
#[derive(Debug)]
91-
pub enum InitError {
92-
InitializationError(io::Error),
93-
AlreadyInitializedError,
94-
}
95-
96-
impl error::Error for InitError {
97-
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
98-
match *self {
99-
InitError::AlreadyInitializedError => None,
100-
InitError::InitializationError(ref error) => Some(error),
101-
}
102-
}
103-
}
104-
105-
impl fmt::Display for InitError {
106-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107-
match self {
108-
Self::AlreadyInitializedError => {
109-
write!(f, "SDL2_TTF has already been initialized")
110-
}
111-
Self::InitializationError(error) => write!(f, "SDL2_TTF initialization error: {error}"),
112-
}
113-
}
91+
Version::from_ll(unsafe { *ttf::TTF_Linked_Version() })
11492
}
11593

11694
/// Initializes the truetype font API and returns a context manager which will
11795
/// clean up the library once it goes out of scope.
118-
pub fn init() -> Result<Sdl2TtfContext, InitError> {
119-
unsafe {
120-
if ttf::TTF_WasInit() == 1 {
121-
Err(InitError::AlreadyInitializedError)
122-
} else if ttf::TTF_Init() == 0 {
123-
Ok(Sdl2TtfContext)
124-
} else {
125-
Err(InitError::InitializationError(io::Error::last_os_error()))
126-
}
96+
#[doc(alias = "TTF_Init")]
97+
pub fn init() -> Result<Sdl2TtfContext, String> {
98+
if unsafe { ttf::TTF_Init() } == 0 {
99+
Ok(Sdl2TtfContext(()))
100+
} else {
101+
Err(get_error())
127102
}
128103
}
129104

130105
/// Returns whether library has been initialized already.
131106
pub fn has_been_initialized() -> bool {
132-
unsafe { ttf::TTF_WasInit() == 1 }
107+
amount_of_times_initialized() != 0
108+
}
109+
110+
fn amount_of_times_initialized() -> c_int {
111+
unsafe { ttf::TTF_WasInit() }
133112
}

src/sdl2/ttf/font.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl<'ttf, 'r> Drop for Font<'ttf, 'r> {
251251
}
252252

253253
/// Internally used to load a font (for internal visibility).
254-
pub fn internal_load_font<'ttf, P: AsRef<Path>>(
254+
pub(super) fn internal_load_font<'ttf, P: AsRef<Path>>(
255255
path: P,
256256
ptsize: u16,
257257
) -> Result<Font<'ttf, 'static>, String> {
@@ -271,7 +271,10 @@ pub fn internal_load_font<'ttf, P: AsRef<Path>>(
271271
}
272272

273273
/// Internally used to load a font (for internal visibility).
274-
pub fn internal_load_font_from_ll<'ttf, 'r, R>(raw: *mut ttf::TTF_Font, rwops: R) -> Font<'ttf, 'r>
274+
pub(super) fn internal_load_font_from_ll<'ttf, 'r, R>(
275+
raw: *mut ttf::TTF_Font,
276+
rwops: R,
277+
) -> Font<'ttf, 'r>
275278
where
276279
R: Into<Option<RWops<'r>>>,
277280
{
@@ -283,7 +286,7 @@ where
283286
}
284287

285288
/// Internally used to load a font (for internal visibility).
286-
pub fn internal_load_font_at_index<'ttf, P: AsRef<Path>>(
289+
pub(super) fn internal_load_font_at_index<'ttf, P: AsRef<Path>>(
287290
path: P,
288291
index: u32,
289292
ptsize: u16,

src/sdl2/ttf/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
mod context;
2424
mod font;
2525

26-
pub use self::context::{
27-
get_linked_version, has_been_initialized, init, InitError, Sdl2TtfContext,
28-
};
26+
pub use self::context::{get_linked_version, has_been_initialized, init, Sdl2TtfContext};
2927
pub use self::font::{
3028
Font, FontError, FontResult, FontStyle, GlyphMetrics, Hinting, PartialRendering,
3129
};

0 commit comments

Comments
 (0)