Skip to content

Commit 1140909

Browse files
authored
Merge pull request #45 from Cobrand/font-lifetime-fix, fix #43 #29
Make Font never outlive its RWops anymore
2 parents c7fd646 + c6bc7cd commit 1140909

File tree

3 files changed

+33
-28
lines changed

3 files changed

+33
-28
lines changed

examples/demo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ fn run(font_path: &Path) {
7575
let padding = 64;
7676
let target = get_centered_rect(width, height, SCREEN_WIDTH - padding, SCREEN_HEIGHT - padding);
7777

78-
renderer.copy(&mut texture, None, Some(target));
78+
renderer.copy(&mut texture, None, Some(target)).unwrap();
7979
renderer.present();
8080

8181
'mainloop: loop {

src/sdl2_ttf/context.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,34 @@ impl Drop for Sdl2TtfContext {
2929

3030
impl Sdl2TtfContext {
3131
/// Loads a font from the given file with the given size in points.
32-
pub fn load_font(&self, path: &Path, point_size: u16) -> Result<Font, String> {
32+
pub fn load_font<'a>(&'a self, path: &'a Path, point_size: u16) -> Result<Font, String> {
3333
internal_load_font(path, point_size)
3434
}
3535

3636
/// Loads the font at the given index of the file, with the given
3737
/// size in points.
38-
pub fn load_font_at_index(&self, path: &Path, index: u32, point_size: u16)
38+
pub fn load_font_at_index<'a>(&'a self, path: &'a Path, index: u32, point_size: u16)
3939
-> Result<Font, String> {
4040
internal_load_font_at_index(path, index, point_size)
4141
}
4242

4343
/// Loads a font from the given SDL2 rwops object with the given size in
4444
/// points.
45-
pub fn load_font_from_rwops(&self, rwops: &mut RWops, point_size: u16)
46-
-> Result<Font, String> {
45+
pub fn load_font_from_rwops<'a>(&'a self, rwops: RWops<'a>, point_size: u16)
46+
-> Result<Font<'a>, String> {
4747
let raw = unsafe {
4848
ffi::TTF_OpenFontRW(rwops.raw(), 0, point_size as c_int)
4949
};
5050
if (raw as *mut ()).is_null() {
5151
Err(get_error())
5252
} else {
53-
Ok(internal_load_font_from_ll(raw, true))
53+
Ok(internal_load_font_from_ll(raw, Some(rwops)))
5454
}
5555
}
5656

5757
/// Loads the font at the given index of the SDL2 rwops object with
5858
/// the given size in points.
59-
pub fn load_font_at_index_from_rwops(&self, rwops: &mut RWops, index: u32,
59+
pub fn load_font_at_index_from_rwops<'a>(&'a self, rwops: RWops<'a>, index: u32,
6060
point_size: u16) -> Result<Font, String> {
6161
let raw = unsafe {
6262
ffi::TTF_OpenFontIndexRW(rwops.raw(), 0, point_size as c_int,
@@ -65,7 +65,7 @@ impl Sdl2TtfContext {
6565
if (raw as *mut ()).is_null() {
6666
Err(get_error())
6767
} else {
68-
Ok(internal_load_font_from_ll(raw, true))
68+
Ok(internal_load_font_from_ll(raw, Some(rwops)))
6969
}
7070
}
7171
}

src/sdl2_ttf/font.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use sdl2::get_error;
1111
use sdl2::pixels;
1212
use sdl2::pixels::Color;
1313
use sdl2_sys::pixels::SDL_Color;
14+
use sdl2::rwops::RWops;
1415
use ffi;
1516

1617
/// Converts a rust-SDL2 color to its C ffi representation.
@@ -139,7 +140,7 @@ impl<'a> RenderableText<'a> {
139140
#[must_use]
140141
pub struct PartialRendering<'a> {
141142
text: RenderableText<'a>,
142-
font: &'a Font,
143+
font: &'a Font<'a>,
143144
}
144145

145146
/// Converts the given raw pointer to a surface.
@@ -246,20 +247,24 @@ impl<'a> PartialRendering<'a> {
246247
}
247248

248249
/// A loaded TTF font.
249-
#[derive(PartialEq)]
250-
pub struct Font {
250+
pub struct Font<'a> {
251251
raw: *const ffi::TTF_Font,
252-
owned: bool
252+
// RWops is only stored here because it must not outlive
253+
// the Font struct, and this RWops should not be used by
254+
// anything else
255+
// None means that the RWops is handled by SDL itself,
256+
// and Some(rwops) means that the RWops is handled by the Rust
257+
// side
258+
#[allow(dead_code)]
259+
rwops:Option<RWops<'a>>
253260
}
254261

255-
impl Drop for Font {
262+
impl<'a> Drop for Font<'a> {
256263
fn drop(&mut self) {
257-
if self.owned {
258-
unsafe {
259-
// avoid close font after quit()
260-
if ffi::TTF_WasInit() == 1 {
261-
ffi::TTF_CloseFont(self.raw);
262-
}
264+
unsafe {
265+
// avoid close font after quit()
266+
if ffi::TTF_WasInit() == 1 {
267+
ffi::TTF_CloseFont(self.raw);
263268
}
264269
}
265270
}
@@ -273,15 +278,15 @@ pub fn internal_load_font(path: &Path, ptsize: u16) -> Result<Font, String> {
273278
if raw.is_null() {
274279
Err(get_error())
275280
} else {
276-
Ok(Font { raw: raw, owned: true })
281+
Ok(Font { raw: raw, rwops: None })
277282
}
278283
}
279284
}
280285

281286
/// Internally used to load a font (for internal visibility).
282-
pub fn internal_load_font_from_ll(raw: *const ffi::TTF_Font, owned: bool)
283-
-> Font {
284-
Font { raw: raw, owned: owned }
287+
pub fn internal_load_font_from_ll<'a>(raw: *const ffi::TTF_Font, rwops: Option<RWops<'a>>)
288+
-> Font<'a> {
289+
Font { raw: raw, rwops: rwops }
285290
}
286291

287292
/// Internally used to load a font (for internal visibility).
@@ -295,35 +300,35 @@ pub fn internal_load_font_at_index(path: &Path, index: u32, ptsize: u16)
295300
if raw.is_null() {
296301
Err(get_error())
297302
} else {
298-
Ok(Font { raw: raw, owned: true })
303+
Ok(Font { raw: raw, rwops: None })
299304
}
300305
}
301306
}
302307

303-
impl Font {
308+
impl<'a> Font<'a> {
304309
/// Returns the underlying C font object.
305310
unsafe fn raw(&self) -> *const ffi::TTF_Font {
306311
self.raw
307312
}
308313

309314
/// Starts specifying a rendering of the given UTF-8-encoded text.
310-
pub fn render<'a>(&'a self, text: &'a str) -> PartialRendering<'a> {
315+
pub fn render(&'a self, text: &'a str) -> PartialRendering<'a> {
311316
PartialRendering {
312317
text: RenderableText::Utf8(text),
313318
font: self,
314319
}
315320
}
316321

317322
/// Starts specifying a rendering of the given Latin-1-encoded text.
318-
pub fn render_latin1<'a>(&'a self, text: &'a [u8]) -> PartialRendering<'a> {
323+
pub fn render_latin1(&'a self, text: &'a [u8]) -> PartialRendering<'a> {
319324
PartialRendering {
320325
text: RenderableText::Latin1(text),
321326
font: self,
322327
}
323328
}
324329

325330
/// Starts specifying a rendering of the given UTF-8-encoded character.
326-
pub fn render_char(&self, ch: char) -> PartialRendering {
331+
pub fn render_char(&'a self, ch: char) -> PartialRendering<'a> {
327332
let mut s = String::new();
328333
s.push(ch);
329334
PartialRendering {

0 commit comments

Comments
 (0)