From bd7075763a372fe532eb7dd97783d3109aa61b87 Mon Sep 17 00:00:00 2001 From: Cobrand Date: Wed, 2 Nov 2016 09:14:24 +0100 Subject: [PATCH] make RWops never outlive its Font --- src/sdl2_ttf/context.rs | 14 ++++++------- src/sdl2_ttf/font.rs | 45 +++++++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/sdl2_ttf/context.rs b/src/sdl2_ttf/context.rs index 4745d865..e67a3021 100644 --- a/src/sdl2_ttf/context.rs +++ b/src/sdl2_ttf/context.rs @@ -29,34 +29,34 @@ impl Drop for Sdl2TtfContext { impl Sdl2TtfContext { /// Loads a font from the given file with the given size in points. - pub fn load_font(&self, path: &Path, point_size: u16) -> Result { + pub fn load_font<'a>(&'a self, path: &'a Path, point_size: u16) -> Result { internal_load_font(path, point_size) } /// Loads the font at the given index of the file, with the given /// size in points. - pub fn load_font_at_index(&self, path: &Path, index: u32, point_size: u16) + pub fn load_font_at_index<'a>(&'a self, path: &'a Path, index: u32, point_size: u16) -> Result { internal_load_font_at_index(path, index, point_size) } /// Loads a font from the given SDL2 rwops object with the given size in /// points. - pub fn load_font_from_rwops(&self, rwops: &mut RWops, point_size: u16) - -> Result { + pub fn load_font_from_rwops<'a>(&'a self, rwops: RWops<'a>, point_size: u16) + -> Result, String> { let raw = unsafe { ffi::TTF_OpenFontRW(rwops.raw(), 0, point_size as c_int) }; if (raw as *mut ()).is_null() { Err(get_error()) } else { - Ok(internal_load_font_from_ll(raw, true)) + Ok(internal_load_font_from_ll(raw, Some(rwops))) } } /// Loads the font at the given index of the SDL2 rwops object with /// the given size in points. - pub fn load_font_at_index_from_rwops(&self, rwops: &mut RWops, index: u32, + pub fn load_font_at_index_from_rwops<'a>(&'a self, rwops: RWops<'a>, index: u32, point_size: u16) -> Result { let raw = unsafe { ffi::TTF_OpenFontIndexRW(rwops.raw(), 0, point_size as c_int, @@ -65,7 +65,7 @@ impl Sdl2TtfContext { if (raw as *mut ()).is_null() { Err(get_error()) } else { - Ok(internal_load_font_from_ll(raw, true)) + Ok(internal_load_font_from_ll(raw, Some(rwops))) } } } diff --git a/src/sdl2_ttf/font.rs b/src/sdl2_ttf/font.rs index 841ab65f..0e843864 100644 --- a/src/sdl2_ttf/font.rs +++ b/src/sdl2_ttf/font.rs @@ -11,6 +11,7 @@ use sdl2::get_error; use sdl2::pixels; use sdl2::pixels::Color; use sdl2_sys::pixels::SDL_Color; +use sdl2::rwops::RWops; use ffi; /// Converts a rust-SDL2 color to its C ffi representation. @@ -139,7 +140,7 @@ impl<'a> RenderableText<'a> { #[must_use] pub struct PartialRendering<'a> { text: RenderableText<'a>, - font: &'a Font, + font: &'a Font<'a>, } /// Converts the given raw pointer to a surface. @@ -246,20 +247,24 @@ impl<'a> PartialRendering<'a> { } /// A loaded TTF font. -#[derive(PartialEq)] -pub struct Font { +pub struct Font<'a> { raw: *const ffi::TTF_Font, - owned: bool + // RWops is only stored here because it must not outlive + // the Font struct, and this RWops should not be used by + // anything else + // None means that the RWops is handled by SDL itself, + // and Some(rwops) means that the RWops is handled by the Rust + // side + #[allow(dead_code)] + rwops:Option> } -impl Drop for Font { +impl<'a> Drop for Font<'a> { fn drop(&mut self) { - if self.owned { - unsafe { - // avoid close font after quit() - if ffi::TTF_WasInit() == 1 { - ffi::TTF_CloseFont(self.raw); - } + unsafe { + // avoid close font after quit() + if ffi::TTF_WasInit() == 1 { + ffi::TTF_CloseFont(self.raw); } } } @@ -273,15 +278,15 @@ pub fn internal_load_font(path: &Path, ptsize: u16) -> Result { if raw.is_null() { Err(get_error()) } else { - Ok(Font { raw: raw, owned: true }) + Ok(Font { raw: raw, rwops: None }) } } } /// Internally used to load a font (for internal visibility). -pub fn internal_load_font_from_ll(raw: *const ffi::TTF_Font, owned: bool) - -> Font { - Font { raw: raw, owned: owned } +pub fn internal_load_font_from_ll<'a>(raw: *const ffi::TTF_Font, rwops: Option>) + -> Font<'a> { + Font { raw: raw, rwops: rwops } } /// Internally used to load a font (for internal visibility). @@ -295,19 +300,19 @@ pub fn internal_load_font_at_index(path: &Path, index: u32, ptsize: u16) if raw.is_null() { Err(get_error()) } else { - Ok(Font { raw: raw, owned: true }) + Ok(Font { raw: raw, rwops: None }) } } } -impl Font { +impl<'a> Font<'a> { /// Returns the underlying C font object. unsafe fn raw(&self) -> *const ffi::TTF_Font { self.raw } /// Starts specifying a rendering of the given UTF-8-encoded text. - pub fn render<'a>(&'a self, text: &'a str) -> PartialRendering<'a> { + pub fn render(&'a self, text: &'a str) -> PartialRendering<'a> { PartialRendering { text: RenderableText::Utf8(text), font: self, @@ -315,7 +320,7 @@ impl Font { } /// Starts specifying a rendering of the given Latin-1-encoded text. - pub fn render_latin1<'a>(&'a self, text: &'a [u8]) -> PartialRendering<'a> { + pub fn render_latin1(&'a self, text: &'a [u8]) -> PartialRendering<'a> { PartialRendering { text: RenderableText::Latin1(text), font: self, @@ -323,7 +328,7 @@ impl Font { } /// Starts specifying a rendering of the given UTF-8-encoded character. - pub fn render_char(&self, ch: char) -> PartialRendering { + pub fn render_char(&'a self, ch: char) -> PartialRendering<'a> { let mut s = String::new(); s.push(ch); PartialRendering {