1 use std::io;
2 use std::error;
3 use std::fmt;
4 use std::os::raw::{c_int, c_long};
5 use std::path::Path;
6 use ::get_error;
7 use ::rwops::RWops;
8 use ::version::Version;
9 use sys;
10
11 use super::font::{
12 internal_load_font,
13 internal_load_font_at_index,
14 internal_load_font_from_ll,
15 Font,
16 };
17
18 /// A context manager for `SDL2_TTF` to manage C code initialization and clean-up.
19 #[must_use]
20 pub struct Sdl2TtfContext;
21
22 // Clean up the context once it goes out of scope
23 impl Drop for Sdl2TtfContext {
drop(&mut self)24 fn drop(&mut self) {
25 unsafe { sys::ttf::TTF_Quit(); }
26 }
27 }
28
29 impl Sdl2TtfContext {
30 /// Loads a font from the given file with the given size in points.
load_font<'ttf, P: AsRef<Path>>(&'ttf self, path: P, point_size: u16) -> Result<Font<'ttf,'static>, String>31 pub fn load_font<'ttf, P: AsRef<Path>>(&'ttf self, path: P, point_size: u16) -> Result<Font<'ttf,'static>, String> {
32 internal_load_font(path, point_size)
33 }
34
35 /// Loads the font at the given index of the file, with the given
36 /// size in points.
load_font_at_index<'ttf, P: AsRef<Path>>(&'ttf self, path: P, index: u32, point_size: u16) -> Result<Font<'ttf,'static>, String>37 pub fn load_font_at_index<'ttf, P: AsRef<Path>>(&'ttf self, path: P, index: u32, point_size: u16)
38 -> Result<Font<'ttf,'static>, String> {
39 internal_load_font_at_index(path, index, point_size)
40 }
41
42 /// Loads a font from the given SDL2 rwops object with the given size in
43 /// points.
load_font_from_rwops<'ttf,'r>(&'ttf self, rwops: RWops<'r>, point_size: u16) -> Result<Font<'ttf,'r>, String>44 pub fn load_font_from_rwops<'ttf,'r>(&'ttf self, rwops: RWops<'r>, point_size: u16)
45 -> Result<Font<'ttf,'r>, String> {
46 let raw = unsafe {
47 sys::ttf::TTF_OpenFontRW(rwops.raw(), 0, point_size as c_int)
48 };
49 if (raw as *mut ()).is_null() {
50 Err(get_error())
51 } else {
52 Ok(internal_load_font_from_ll(raw, Some(rwops)))
53 }
54 }
55
56 /// Loads the font at the given index of the SDL2 rwops object with
57 /// the given size in points.
load_font_at_index_from_rwops<'ttf,'r>(&'ttf self, rwops: RWops<'r>, index: u32, point_size: u16) -> Result<Font<'ttf,'r>, String>58 pub fn load_font_at_index_from_rwops<'ttf,'r>(&'ttf self, rwops: RWops<'r>, index: u32,
59 point_size: u16) -> Result<Font<'ttf,'r>, String> {
60 let raw = unsafe {
61 sys::ttf::TTF_OpenFontIndexRW(rwops.raw(), 0, point_size as c_int,
62 index as c_long)
63 };
64 if (raw as *mut ()).is_null() {
65 Err(get_error())
66 } else {
67 Ok(internal_load_font_from_ll(raw, Some(rwops)))
68 }
69 }
70 }
71
72 /// Returns the version of the dynamically linked `SDL_TTF` library
get_linked_version() -> Version73 pub fn get_linked_version() -> Version {
74 unsafe {
75 Version::from_ll(*sys::ttf::TTF_Linked_Version())
76 }
77 }
78
79 /// An error for when `sdl2_ttf` is attempted initialized twice
80 /// Necessary for context management, unless we find a way to have a singleton
81 #[derive(Debug)]
82 pub enum InitError {
83 InitializationError(io::Error),
84 AlreadyInitializedError,
85 }
86
87 impl error::Error for InitError {
description(&self) -> &str88 fn description(&self) -> &str {
89 match *self {
90 InitError::AlreadyInitializedError => {
91 "SDL2_TTF has already been initialized"
92 },
93 InitError::InitializationError(ref error) => {
94 error.description()
95 },
96 }
97 }
98
cause(&self) -> Option<&error::Error>99 fn cause(&self) -> Option<&error::Error> {
100 match *self {
101 InitError::AlreadyInitializedError => {
102 None
103 },
104 InitError::InitializationError(ref error) => {
105 Some(error)
106 },
107 }
108 }
109 }
110
111 impl fmt::Display for InitError {
fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error>112 fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
113 formatter.write_str("SDL2_TTF has already been initialized")
114 }
115 }
116
117 /// Initializes the truetype font API and returns a context manager which will
118 /// clean up the library once it goes out of scope.
init() -> Result<Sdl2TtfContext, InitError>119 pub fn init() -> Result<Sdl2TtfContext, InitError> {
120 unsafe {
121 if sys::ttf::TTF_WasInit() == 1 {
122 Err(InitError::AlreadyInitializedError)
123 } else if sys::ttf::TTF_Init() == 0 {
124 Ok(Sdl2TtfContext)
125 } else {
126 Err(InitError::InitializationError(
127 io::Error::last_os_error()
128 ))
129 }
130 }
131 }
132
133 /// Returns whether library has been initialized already.
has_been_initialized() -> bool134 pub fn has_been_initialized() -> bool {
135 unsafe {
136 sys::ttf::TTF_WasInit() == 1
137 }
138 }
139