pushrod/render/texture_cache.rs
1// Pushrod Rendering Library
2// Texture Caching Component
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use sdl2::image::LoadTexture;
17use sdl2::pixels::Color;
18use sdl2::render::{Canvas, Texture, TextureQuery};
19use sdl2::ttf::{FontStyle, Sdl2TtfContext};
20use sdl2::video::Window;
21use std::collections::HashMap;
22use std::path::Path;
23
24/// This is the structure for the `TextureCache`.
25pub struct TextureCache {
26 images: HashMap<String, Texture>,
27 ttf_context: Sdl2TtfContext,
28}
29
30/// This is a `Texture` cache object that is used by the `WidgetCache`. This is responsible for loading
31/// in images into a cache in memory so that it can be copied multiple times as required by the
32/// application.
33impl TextureCache {
34 /// Creates a new `TextureCache`.
35 pub fn new() -> Self {
36 Self {
37 images: HashMap::new(),
38 ttf_context: sdl2::ttf::init().map_err(|e| e.to_string()).unwrap(),
39 }
40 }
41
42 /// Retrieves the current Text Rendering context (`Sdl2TtfContext`)
43 pub fn get_ttf_context(&self) -> &Sdl2TtfContext {
44 &self.ttf_context
45 }
46
47 /// Loads an image based on the `image_name`, which is the filename for the image to load.
48 /// Returns a reference to the `Texture` that was loaded.
49 pub fn get_image(&mut self, c: &mut Canvas<Window>, image_name: String) -> &Texture {
50 self.images.entry(image_name.clone()).or_insert({
51 c.texture_creator()
52 .load_texture(Path::new(&image_name))
53 .unwrap()
54 })
55 }
56
57 /// Renders text, given the font name, size, style, color, string, and max width. Transfers
58 /// ownership of the `Texture` to the calling function, returns the width and height of the
59 /// texture after rendering. By using the identical font name, size, and style, if SDL2 caches
60 /// the font data, this will allow the font to be cached internally.
61 pub fn render_text(
62 &mut self,
63 c: &mut Canvas<Window>,
64 font_name: String,
65 font_size: u16,
66 font_style: FontStyle,
67 font_string: String,
68 font_color: Color,
69 width: u32,
70 ) -> (Texture, u32, u32) {
71 let ttf_context = self.get_ttf_context();
72 let texture_creator = c.texture_creator();
73 let mut font = ttf_context
74 .load_font(Path::new(&font_name), font_size as u16)
75 .unwrap();
76
77 font.set_style(font_style);
78
79 let surface = font
80 .render(&font_string)
81 .blended_wrapped(font_color, width)
82 .map_err(|e| e.to_string())
83 .unwrap();
84 let font_texture = texture_creator
85 .create_texture_from_surface(&surface)
86 .map_err(|e| e.to_string())
87 .unwrap();
88
89 let TextureQuery { width, height, .. } = font_texture.query();
90
91 (font_texture, width, height)
92 }
93}
94
95impl Default for TextureCache {
96 fn default() -> Self {
97 Self::new()
98 }
99}