1 extern crate sdl2;
2
3 use std::env;
4 use std::path::Path;
5
6 use sdl2::event::Event;
7 use sdl2::keyboard::Keycode;
8 use sdl2::rect::Rect;
9 use sdl2::render::TextureQuery;
10 use sdl2::pixels::Color;
11
12 static SCREEN_WIDTH : u32 = 800;
13 static SCREEN_HEIGHT : u32 = 600;
14
15 // handle the annoying Rect i32
16 macro_rules! rect(
17 ($x:expr, $y:expr, $w:expr, $h:expr) => (
18 Rect::new($x as i32, $y as i32, $w as u32, $h as u32)
19 )
20 );
21
22 // Scale fonts to a reasonable size when they're too big (though they might look less smooth)
get_centered_rect(rect_width: u32, rect_height: u32, cons_width: u32, cons_height: u32) -> Rect23 fn get_centered_rect(rect_width: u32, rect_height: u32, cons_width: u32, cons_height: u32) -> Rect {
24 let wr = rect_width as f32 / cons_width as f32;
25 let hr = rect_height as f32 / cons_height as f32;
26
27 let (w, h) = if wr > 1f32 || hr > 1f32 {
28 if wr > hr {
29 println!("Scaling down! The text will look worse!");
30 let h = (rect_height as f32 / wr) as i32;
31 (cons_width as i32, h)
32 } else {
33 println!("Scaling down! The text will look worse!");
34 let w = (rect_width as f32 / hr) as i32;
35 (w, cons_height as i32)
36 }
37 } else {
38 (rect_width as i32, rect_height as i32)
39 };
40
41 let cx = (SCREEN_WIDTH as i32 - w) / 2;
42 let cy = (SCREEN_HEIGHT as i32 - h) / 2;
43 rect!(cx, cy, w, h)
44 }
45
run(font_path: &Path) -> Result<(), String>46 fn run(font_path: &Path) -> Result<(), String> {
47 let sdl_context = sdl2::init()?;
48 let video_subsys = sdl_context.video()?;
49 let ttf_context = sdl2::ttf::init().map_err(|e| e.to_string())?;
50
51 let window = video_subsys.window("SDL2_TTF Example", SCREEN_WIDTH, SCREEN_HEIGHT)
52 .position_centered()
53 .opengl()
54 .build()
55 .map_err(|e| e.to_string())?;
56
57 let mut canvas = window.into_canvas().build().map_err(|e| e.to_string())?;
58 let texture_creator = canvas.texture_creator();
59
60 // Load a font
61 let mut font = ttf_context.load_font(font_path, 128)?;
62 font.set_style(sdl2::ttf::FontStyle::BOLD);
63
64 // render a surface, and convert it to a texture bound to the canvas
65 let surface = font.render("Hello Rust!")
66 .blended(Color::RGBA(255, 0, 0, 255)).map_err(|e| e.to_string())?;
67 let texture = texture_creator.create_texture_from_surface(&surface)
68 .map_err(|e| e.to_string())?;
69
70 canvas.set_draw_color(Color::RGBA(195, 217, 255, 255));
71 canvas.clear();
72
73 let TextureQuery { width, height, .. } = texture.query();
74
75 // If the example text is too big for the screen, downscale it (and center irregardless)
76 let padding = 64;
77 let target = get_centered_rect(width, height, SCREEN_WIDTH - padding, SCREEN_HEIGHT - padding);
78
79 canvas.copy(&texture, None, Some(target))?;
80 canvas.present();
81
82 'mainloop: loop {
83 for event in sdl_context.event_pump()?.poll_iter() {
84 match event {
85 Event::KeyDown {keycode: Some(Keycode::Escape), ..} |
86 Event::Quit {..} => break 'mainloop,
87 _ => {}
88 }
89 }
90 }
91
92 Ok(())
93 }
94
main() -> Result<(), String>95 fn main() -> Result<(), String> {
96 let args: Vec<_> = env::args().collect();
97
98 println!("linked sdl2_ttf: {}", sdl2::ttf::get_linked_version());
99
100 if args.len() < 2 {
101 println!("Usage: ./demo font.[ttf|ttc|fon]")
102 } else {
103 let path: &Path = Path::new(&args[1]);
104 run(path)?;
105 }
106
107 Ok(())
108 }
109