Skip to content

Commit 04e9b69

Browse files
committed
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 Rust-SDL2#1348, fixes Rust-SDL2#1347 and closes Rust-SDL2#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)
1 parent 863399d commit 04e9b69

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

src/sdl2/ttf/context.rs

+23-17
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,22 +88,21 @@ 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()) }
91+
Version::from_ll(unsafe { *ttf::TTF_Linked_Version() })
8692
}
8793

8894
/// An error for when `sdl2_ttf` is attempted initialized twice
8995
/// Necessary for context management, unless we find a way to have a singleton
9096
#[derive(Debug)]
9197
pub enum InitError {
92-
InitializationError(io::Error),
98+
InitializationError(String),
9399
AlreadyInitializedError,
94100
}
95101

96102
impl error::Error for InitError {
97103
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
98104
match *self {
99-
InitError::AlreadyInitializedError => None,
100-
InitError::InitializationError(ref error) => Some(error),
105+
InitError::InitializationError(_) | InitError::AlreadyInitializedError => None,
101106
}
102107
}
103108
}
@@ -115,19 +120,20 @@ impl fmt::Display for InitError {
115120

116121
/// Initializes the truetype font API and returns a context manager which will
117122
/// clean up the library once it goes out of scope.
123+
#[doc(alias = "TTF_Init")]
118124
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-
}
125+
if unsafe { ttf::TTF_Init() } == 0 {
126+
Ok(Sdl2TtfContext(()))
127+
} else {
128+
Err(InitError::InitializationError(get_error()))
127129
}
128130
}
129131

130132
/// Returns whether library has been initialized already.
131133
pub fn has_been_initialized() -> bool {
132-
unsafe { ttf::TTF_WasInit() == 1 }
134+
amount_of_times_initialized() != 0
135+
}
136+
137+
fn amount_of_times_initialized() -> c_int {
138+
unsafe { ttf::TTF_WasInit() }
133139
}

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,

0 commit comments

Comments
 (0)