Struct Text

Source
pub struct Text<'s> { /* private fields */ }
Expand description

Graphical text

Text is a drawable type that allows to easily display some text with custom style and color on a render target.

Note: Currently, it is not feasible to store text long term. A common pattern with rust-sfml is to create a Text right before you start drawing, and draw all the text you want with it. You can change its properties using set_font, set_position, set_string, etc., before drawing it, as many times as you need to.

Implementations§

Source§

impl<'s> Text<'s>

Source

pub fn new<S: SfStrConv>( string: S, font: &'s Font, character_size: u32, ) -> Text<'s>

Create a new text with initialized value

Default value for characterSize on SFML is 30.

§Arguments
  • string - The string of the text
  • font - The font to display the Text
  • characterSize - The size of the Text
Examples found in repository?
examples/custom-sound-recorder.rs (line 43)
41    fn new(font: &'font Font, font_size: u32, x: f32, init_y: f32) -> Self {
42        Self {
43            text: Text::new("", font, font_size),
44            x,
45            y_cursor: init_y,
46            font_size,
47        }
48    }
More examples
Hide additional examples
examples/shader.rs (line 88)
87    fn new(font: &'fo Font) -> SfResult<Self> {
88        let mut text = Text::new(WAVEBLUR_TEXT, font, 22);
89        text.set_position((30., 20.));
90        Ok(Self {
91            text,
92            shader: Shader::from_file_vert_frag("wave.vert", "blur.frag")?,
93        })
94    }
95}
96
97impl Drawable for WaveBlur<'_> {
98    fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
99        &'a self,
100        target: &mut dyn RenderTarget,
101        states: &RenderStates<'texture, 'shader, 'shader_texture>,
102    ) {
103        let mut states = *states;
104        states.shader = Some(&self.shader);
105        target.draw_with_renderstates(&self.text, &states);
106    }
107}
108
109impl Effect for WaveBlur<'_> {
110    fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
111        self.shader.set_uniform_float("wave_phase", t)?;
112        self.shader
113            .set_uniform_vec2("wave_amplitude", Vector2f::new(x * 40., y * 40.))?;
114        self.shader
115            .set_uniform_float("blur_radius", (x + y) * 0.008)
116    }
117    fn name(&self) -> &str {
118        "wave + blur"
119    }
120    fn as_drawable(&self) -> &dyn Drawable {
121        self
122    }
123}
124
125struct StormBlink {
126    points: Vec<Vertex>,
127    shader: FBox<Shader<'static>>,
128}
129
130impl StormBlink {
131    fn new() -> SfResult<Self> {
132        use rand::{thread_rng, Rng};
133        let mut rng = thread_rng();
134
135        let mut points = Vec::new();
136        for _ in 0..40_000 {
137            let x = rng.gen_range(0.0..800.);
138            let y = rng.gen_range(0.0..600.);
139            let (red, green, blue) = (rng.r#gen(), rng.r#gen(), rng.r#gen());
140            points.push(Vertex::with_pos_color(
141                Vector2f::new(x, y),
142                Color::rgb(red, green, blue),
143            ));
144        }
145
146        let shader = Shader::from_file_vert_frag("storm.vert", "blink.frag")?;
147        Ok(Self { points, shader })
148    }
149}
150
151impl Drawable for StormBlink {
152    fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
153        &'a self,
154        target: &mut dyn RenderTarget,
155        states: &RenderStates<'texture, 'shader, 'shader_texture>,
156    ) {
157        let mut states = *states;
158        states.shader = Some(&self.shader);
159        target.draw_primitives(&self.points, PrimitiveType::POINTS, &states);
160    }
161}
162
163impl Effect for StormBlink {
164    fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
165        let radius = 200. + t.cos() * 150.;
166        self.shader
167            .set_uniform_vec2("storm_position", Vector2f::new(x * 800., y * 600.))?;
168        self.shader
169            .set_uniform_float("storm_inner_radius", radius / 3.)?;
170        self.shader
171            .set_uniform_float("storm_total_radius", radius)?;
172        self.shader
173            .set_uniform_float("blink_alpha", 0.5 + (t * 3.).cos() * 0.25)
174    }
175    fn name(&self) -> &str {
176        "storm + blink"
177    }
178    fn as_drawable(&self) -> &dyn Drawable {
179        self
180    }
181}
182
183struct Edge<'t> {
184    surface: FBox<RenderTexture>,
185    bg_sprite: Sprite<'t>,
186    entities: Vec<Sprite<'t>>,
187    shader: FBox<Shader<'static>>,
188}
189
190impl<'t> Edge<'t> {
191    fn new(bg_texture: &'t Texture, entity_texture: &'t Texture) -> SfResult<Self> {
192        let mut surface = RenderTexture::new(800, 600)?;
193        surface.set_smooth(true);
194        let mut bg_sprite = Sprite::with_texture(bg_texture);
195        bg_sprite.set_position((135., 100.));
196        let mut entities = Vec::new();
197
198        for i in 0..6 {
199            entities.push(Sprite::with_texture_and_rect(
200                entity_texture,
201                IntRect::new(96 * i, 0, 96, 96),
202            ));
203        }
204
205        let mut shader = Shader::from_file("edge.frag", ShaderType::Fragment)?;
206        shader.set_uniform_current_texture("texture")?;
207
208        Ok(Self {
209            surface,
210            bg_sprite,
211            entities,
212            shader,
213        })
214    }
215}
216
217impl Drawable for Edge<'_> {
218    fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
219        &'a self,
220        target: &mut dyn RenderTarget,
221        states: &RenderStates<'texture, 'shader, 'shader_texture>,
222    ) {
223        let mut states = *states;
224        states.shader = Some(&self.shader);
225        target.draw_with_renderstates(&Sprite::with_texture(self.surface.texture()), &states);
226    }
227}
228
229impl Effect for Edge<'_> {
230    fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
231        self.shader
232            .set_uniform_float("edge_threshold", 1. - (x + y) / 2.)?;
233        let entities_len = self.entities.len() as f32;
234
235        for (i, en) in self.entities.iter_mut().enumerate() {
236            let pos = (
237                (0.25 * (t * i as f32 + (entities_len - i as f32))).cos() * 300. + 350.,
238                (0.25 * (t * (entities_len - i as f32) + i as f32)).cos() * 200. + 250.,
239            );
240            en.set_position(pos);
241        }
242        self.surface.clear(Color::WHITE);
243        self.surface.draw(&self.bg_sprite);
244        for en in &self.entities {
245            self.surface.draw(en);
246        }
247        self.surface.display();
248        Ok(())
249    }
250    fn as_drawable(&self) -> &dyn Drawable {
251        self
252    }
253    fn name(&self) -> &str {
254        "edge post-effect"
255    }
256}
257
258fn main() -> SfResult<()> {
259    example_ensure_right_working_dir();
260
261    let mut window = RenderWindow::new(
262        (800, 600),
263        "SFML Shader",
264        Style::TITLEBAR | Style::CLOSE,
265        &Default::default(),
266    )?;
267    window.set_vertical_sync_enabled(true);
268    let font = Font::from_file("sansation.ttf")?;
269    let bg = Texture::from_file("background.jpg")?;
270    let mut bg_texture = Texture::from_file("sfml.png")?;
271    bg_texture.set_smooth(true);
272    let mut entity_texture = Texture::from_file("devices.png")?;
273    entity_texture.set_smooth(true);
274    let effects: [&mut dyn Effect; 4] = [
275        &mut Pixelate::new(&bg)?,
276        &mut WaveBlur::new(&font)?,
277        &mut StormBlink::new()?,
278        &mut Edge::new(&bg_texture, &entity_texture)?,
279    ];
280    let mut current = 0;
281    let text_bg_texture = Texture::from_file("text-background.png")?;
282    let mut text_bg = Sprite::with_texture(&text_bg_texture);
283    text_bg.set_position((0., 520.));
284    text_bg.set_color(Color::rgba(255, 255, 255, 200));
285    let msg = format!("Current effect: {}", effects[current].name());
286    let mut desc = Text::new(&msg, &font, 20);
287    desc.set_position((10., 530.));
288    desc.set_fill_color(Color::rgb(80, 80, 80));
289    let msg = "Press left and right arrows to change the current shader";
290    let mut instructions = Text::new(msg, &font, 20);
291    instructions.set_position((280., 555.));
292    instructions.set_fill_color(Color::rgb(80, 80, 80));
293    let clock = Clock::start()?;
294
295    while window.is_open() {
296        while let Some(event) = window.poll_event() {
297            use crate::Event::*;
298            match event {
299                Closed => window.close(),
300                KeyPressed { code, .. } => match code {
301                    Key::Escape => window.close(),
302                    Key::Left => {
303                        if current == 0 {
304                            current = effects.len() - 1;
305                        } else {
306                            current -= 1;
307                        }
308                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
309                    }
310                    Key::Right => {
311                        if current == effects.len() - 1 {
312                            current = 0;
313                        } else {
314                            current += 1;
315                        }
316                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
317                    }
318                    _ => {}
319                },
320                _ => {}
321            }
322        }
323
324        let x = window.mouse_position().x as f32 / window.size().x as f32;
325        let y = window.mouse_position().y as f32 / window.size().y as f32;
326
327        effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
328
329        window.clear(Color::rgb(255, 128, 0));
330        window.draw(effects[current].as_drawable());
331        window.draw(&text_bg);
332        window.draw(&instructions);
333        window.draw(&desc);
334        window.display();
335    }
336    Ok(())
337}
examples/borrowed-resources.rs (line 51)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "Borrowed resources",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Create a new texture. (Hey Frank!)
24    let frank = Texture::from_file("frank.jpeg")?;
25
26    // Create a font.
27    let font = Font::from_file("sansation.ttf")?;
28
29    // Create a circle with the Texture.
30    let mut circle = CircleShape::with_texture(&frank);
31    circle.set_radius(70.0);
32    circle.set_position((100.0, 100.0));
33
34    // Create a Sprite.
35    let mut sprite = Sprite::new();
36    // Have it use the same texture as the circle.
37    sprite.set_texture(&frank, true);
38    sprite.set_position((400.0, 300.0));
39    sprite.set_scale(0.5);
40
41    // Create a ConvexShape using the same texture.
42    let mut convex_shape = ConvexShape::with_texture(6, &frank);
43    convex_shape.set_point(0, (400., 100.));
44    convex_shape.set_point(1, (500., 70.));
45    convex_shape.set_point(2, (450., 100.));
46    convex_shape.set_point(3, (580., 150.));
47    convex_shape.set_point(4, (420., 230.));
48    convex_shape.set_point(5, (420., 120.));
49
50    // Create an initialized text using the font.
51    let title = Text::new("Borrowed resources example!", &font, 50);
52
53    // Create a second text using the same font.
54    // This time, we create and initialize it separately.
55    let mut second_text = Text::default();
56    second_text.set_string("This text shares the same font with the title!");
57    second_text.set_font(&font);
58    second_text.set_fill_color(Color::GREEN);
59    second_text.set_position((10.0, 350.0));
60    second_text.set_character_size(20);
61
62    // Create a third text using the same font.
63    let mut third_text = Text::new("This one too!", &font, 20);
64    third_text.set_position((300.0, 100.0));
65    third_text.set_fill_color(Color::RED);
66
67    'mainloop: loop {
68        while let Some(event) = window.poll_event() {
69            match event {
70                Event::Closed
71                | Event::KeyPressed {
72                    code: Key::Escape, ..
73                } => break 'mainloop,
74                _ => {}
75            }
76        }
77
78        window.clear(Color::BLACK);
79        window.draw(&circle);
80        window.draw(&sprite);
81        window.draw(&convex_shape);
82        window.draw(&title);
83        window.draw(&second_text);
84        window.draw(&third_text);
85
86        // Little test here for `Shape::points`
87        let mut circ = CircleShape::new(4.0, 30);
88        circ.set_origin(2.0);
89        circ.set_fill_color(Color::YELLOW);
90
91        for p in convex_shape.points() {
92            circ.set_position(p);
93            window.draw(&circ);
94        }
95
96        window.display();
97    }
98    Ok(())
99}
examples/mouse.rs (line 20)
5fn main() -> SfResult<()> {
6    example_ensure_right_working_dir();
7
8    let mut window = RenderWindow::new(
9        (800, 600),
10        "Mouse events",
11        Style::CLOSE,
12        &Default::default(),
13    )?;
14    window.set_mouse_cursor_visible(false);
15    window.set_vertical_sync_enabled(true);
16
17    let font = Font::from_file("sansation.ttf")?;
18    let mut circle = CircleShape::new(4., 30);
19    let mut texts: Vec<Text> = Vec::new();
20    let mut mp_text = Text::new("", &font, 14);
21    let mut cursor_visible = false;
22    let mut grabbed = false;
23    macro_rules! push_text {
24        ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25            let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26            text.set_position(($x as f32, $y as f32));
27            texts.push(text);
28        }
29    }
30
31    'mainloop: loop {
32        while let Some(ev) = window.poll_event() {
33            match ev {
34                Event::Closed => break 'mainloop,
35                Event::MouseWheelScrolled { wheel, delta, x, y } => {
36                    push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37                }
38                Event::MouseButtonPressed { button, x, y } => {
39                    push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40                }
41                Event::MouseButtonReleased { button, x, y } => {
42                    push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43                }
44                Event::KeyPressed { code, .. } => {
45                    if code == Key::W {
46                        window.set_mouse_position(Vector2i::new(400, 300));
47                    } else if code == Key::D {
48                        let dm = VideoMode::desktop_mode();
49                        let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50                        mouse::set_desktop_position(center);
51                    } else if code == Key::V {
52                        cursor_visible = !cursor_visible;
53                        window.set_mouse_cursor_visible(cursor_visible);
54                    } else if code == Key::G {
55                        grabbed = !grabbed;
56                        window.set_mouse_cursor_grabbed(grabbed);
57                    }
58                }
59                _ => {}
60            }
61        }
62
63        let mp = window.mouse_position();
64        let dmp = mouse::desktop_position();
65        let cur_vis_msg = if cursor_visible {
66            "visible"
67        } else {
68            "invisible"
69        };
70        let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71        mp_text.set_string(&format!(
72            "x: {}, y: {} (Window)\n\
73             x: {}, y: {} (Desktop)\n\
74             [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75             'W' to center mouse on window\n\
76             'D' to center mouse on desktop",
77            mp.x, mp.y, dmp.x, dmp.y
78        ));
79
80        circle.set_position((mp.x as f32, mp.y as f32));
81
82        window.clear(Color::BLACK);
83        // Push texts out of each other's way
84        for i in (0..texts.len()).rev() {
85            for j in (0..i).rev() {
86                if let Some(intersect) = texts[i]
87                    .global_bounds()
88                    .intersection(&texts[j].global_bounds())
89                {
90                    texts[j].move_((0., -intersect.height));
91                }
92            }
93        }
94        texts.retain(|txt| txt.fill_color().a > 0);
95        for txt in &mut texts {
96            let mut color = txt.fill_color();
97            color.a -= 1;
98            txt.set_fill_color(color);
99            window.draw(txt);
100        }
101        if !cursor_visible {
102            window.draw(&circle);
103        }
104        window.draw(&mp_text);
105        window.display();
106    }
107    Ok(())
108}
examples/window-test.rs (line 75)
13fn main() -> SfResult<()> {
14    let configs = [
15        WindowConfig {
16            mode: (320, 240),
17            title: "(Windowed) Retro",
18            style: Style::CLOSE,
19        },
20        WindowConfig {
21            mode: (640, 480),
22            title: "(Windowed) Classic",
23            style: Style::DEFAULT,
24        },
25        WindowConfig {
26            mode: (800, 600),
27            title: "(Windowed) Big",
28            style: Style::TITLEBAR,
29        },
30    ];
31    let mut cfg_idx = 2usize;
32    let mut rw = RenderWindow::new(
33        configs[cfg_idx].mode,
34        "Window test",
35        Style::CLOSE,
36        &ContextSettings::default(),
37    )?;
38    let font = Font::from_memory_static(include_bytes!("resources/sansation.ttf"))?;
39    let fs_modes = VideoMode::fullscreen_modes();
40
41    while rw.is_open() {
42        while let Some(ev) = rw.poll_event() {
43            match ev {
44                Event::Closed => rw.close(),
45                Event::KeyPressed { code, .. } => match code {
46                    Key::Up => cfg_idx = cfg_idx.saturating_sub(1),
47                    Key::Down => {
48                        if cfg_idx + 1 < configs.len() + fs_modes.len() {
49                            cfg_idx += 1
50                        }
51                    }
52                    Key::Enter => match configs.get(cfg_idx) {
53                        Some(cfg) => {
54                            rw.recreate(cfg.mode, cfg.title, cfg.style, &ContextSettings::default())
55                        }
56                        None => match fs_modes.get(cfg_idx - configs.len()) {
57                            Some(mode) => rw.recreate(
58                                *mode,
59                                "Fullscreen",
60                                Style::FULLSCREEN,
61                                &ContextSettings::default(),
62                            ),
63                            None => {
64                                eprintln!("Invalid index: {cfg_idx}");
65                            }
66                        },
67                    },
68                    _ => {}
69                },
70                _ => {}
71            }
72        }
73        rw.clear(Color::BLACK);
74        let fontsize = 16;
75        let mut txt = Text::new("Arrow keys to select mode, enter to set.", &font, fontsize);
76        rw.draw(&txt);
77        let mut y = fontsize as f32;
78        for (i, cfg) in configs.iter().enumerate() {
79            let fc = if i == cfg_idx {
80                Color::YELLOW
81            } else {
82                Color::WHITE
83            };
84            txt.set_fill_color(fc);
85            txt.set_string(&format!(
86                "{}x{} \"{}\" ({:?})",
87                cfg.mode.0, cfg.mode.1, cfg.title, cfg.style
88            ));
89            txt.set_position((0., y));
90            rw.draw(&txt);
91            y += fontsize as f32;
92        }
93        let mut i = configs.len();
94        y += fontsize as f32;
95        txt.set_position((0., y));
96        txt.set_fill_color(Color::WHITE);
97        txt.set_string("= Fullscreen modes =");
98        rw.draw(&txt);
99        for mode in fs_modes.iter() {
100            let n_rows = 23;
101            let column = i / n_rows;
102            let row = i % n_rows;
103            let fc = if i == cfg_idx {
104                Color::YELLOW
105            } else {
106                Color::WHITE
107            };
108            txt.set_fill_color(fc);
109            let left_pad = 16.0;
110            let x = left_pad + (column * 128) as f32;
111            let gap = 16.0;
112            let y = y + gap + (row * fontsize as usize) as f32;
113            txt.set_position((x, y));
114            txt.set_string(&format!(
115                "{}x{}x{}",
116                mode.width, mode.height, mode.bits_per_pixel
117            ));
118            rw.draw(&txt);
119            i += 1;
120        }
121        rw.display();
122    }
123    Ok(())
124}
examples/positional-audio.rs (line 57)
46fn main() -> Result<(), Box<dyn Error>> {
47    example_ensure_right_working_dir();
48
49    let mut rw = RenderWindow::new(
50        (800, 600),
51        "Positional audio demo",
52        Style::CLOSE,
53        &Default::default(),
54    )?;
55    rw.set_vertical_sync_enabled(true);
56    let font = Font::from_file("sansation.ttf")?;
57    let mut text = Text::new("", &font, 20);
58    let mut music = match std::env::args().nth(1) {
59        Some(music_path) => Music::from_file(&music_path)?,
60        None => Music::from_file("canary.wav")?,
61    };
62    if music.channel_count() != 1 {
63        return Err("Sorry, only sounds with 1 channel are supported.".into());
64    };
65    music.set_looping(true);
66    music.play();
67    music.set_position(Vector3::new(0., 0., 0.));
68
69    let mut listener_pos = Vector3::new(0.0, 0.0, 0.0);
70    let center = Vector2::new(400., 300.);
71    let [mut go_left, mut go_right, mut go_up, mut go_down] = [false; 4];
72    let clock = Clock::start()?;
73
74    while rw.is_open() {
75        while let Some(ev) = rw.poll_event() {
76            match ev {
77                Event::Closed => rw.close(),
78                Event::KeyPressed { code, .. } => match code {
79                    Key::A => go_left = true,
80                    Key::D => go_right = true,
81                    Key::W => go_up = true,
82                    Key::S => go_down = true,
83                    _ => {}
84                },
85                Event::KeyReleased { code, .. } => match code {
86                    Key::A => go_left = false,
87                    Key::D => go_right = false,
88                    Key::W => go_up = false,
89                    Key::S => go_down = false,
90                    _ => {}
91                },
92                _ => {}
93            }
94        }
95        let Vector2f { x: mx, y: my } = rw.mouse_position().as_other();
96        let speed = 0.05;
97        if go_left {
98            listener_pos.x -= speed;
99        }
100        if go_right {
101            listener_pos.x += speed;
102        }
103        if go_up {
104            listener_pos.y -= speed;
105        }
106        if go_down {
107            listener_pos.y += speed;
108        }
109        let scale = 20.0; // Scale the positions for better visualization
110        listener::set_position(listener_pos);
111        listener::set_direction(Vector3::new(
112            (mx - center.x) / scale,
113            (my - center.y) / scale,
114            -1.,
115        ));
116        let Vector3 {
117            x: lx,
118            y: ly,
119            z: lz,
120        } = listener::position();
121        let Vector3 {
122            x: dx,
123            y: dy,
124            z: dz,
125        } = listener::direction();
126        rw.clear(Color::BLACK);
127        let mut circle_shape = CircleShape::new(8.0, 32);
128        // Draw circle at center, representing position of music being played
129        circle_shape.set_position(center);
130        circle_shape.set_fill_color(Color::YELLOW);
131        let t = clock.elapsed_time().as_seconds();
132        let radius = 12.0 + t.sin() * 3.0;
133        circle_shape.set_radius(radius);
134        circle_shape.set_origin(radius);
135        rw.draw(&circle_shape);
136        // Draw circle representing listener
137        circle_shape.set_position((center.x + lx * scale, center.y + ly * scale));
138        circle_shape.set_origin(4.0);
139        circle_shape.set_radius(4.0);
140        circle_shape.set_fill_color(Color::GREEN);
141        rw.draw(&circle_shape);
142        // Draw line from listener to direction vector position
143        rw.draw_line(
144            circle_shape.position(),
145            (center.x + dx * scale, center.y + dy * scale).into(),
146            2.0,
147        );
148        text.set_string("WASD + mouse for movement of listener");
149        text.set_position(0.);
150        rw.draw(&text);
151        text.set_string(&format!("Listener position: {lx}, {ly}, {lz}"));
152        text.set_position((0., 20.0));
153        rw.draw(&text);
154        text.set_string(&format!("Listener direction: {dx}, {dy}, {dz}"));
155        text.set_position((0., 40.0));
156        rw.draw(&text);
157        rw.display();
158    }
159    Ok(())
160}
Source

pub fn set_string<S: SfStrConv>(&mut self, string: S)

Set the string of a text

A text’s string is empty by default.

§Arguments
  • string - New string
Examples found in repository?
examples/custom-sound-recorder.rs (line 50)
49    fn write(&mut self, text: &str, rw: &mut RenderWindow) {
50        self.text.set_string(text);
51        self.text.set_position((self.x, self.y_cursor));
52        rw.draw(&self.text);
53        self.y_cursor += self.font_size as f32 + 4.0;
54    }
More examples
Hide additional examples
examples/cursor.rs (line 55)
35fn draw_button(
36    rect: &Rect<i32>,
37    shape: &mut RectangleShape,
38    text: &mut Text,
39    string: &str,
40    render_window: &mut RenderWindow,
41    style: ButtonStyle,
42) {
43    shape.set_position((rect.left as f32, rect.top as f32));
44    shape.set_size((rect.width as f32, rect.height as f32));
45    let (rect_fill, rect_outline, text_fill) = match style {
46        ButtonStyle::Normal => (Color::TRANSPARENT, Color::WHITE, Color::WHITE),
47        ButtonStyle::Highlighted => (Color::WHITE, Color::WHITE, Color::BLACK),
48        ButtonStyle::Selected => (Color::GREEN, Color::GREEN, Color::BLACK),
49        ButtonStyle::Error => (Color::RED, Color::BLACK, Color::BLACK),
50    };
51    shape.set_outline_color(rect_outline);
52    shape.set_fill_color(rect_fill);
53    text.set_position((rect.left as f32 + 12.0, rect.top as f32 + 8.0));
54    text.set_fill_color(text_fill);
55    text.set_string(string);
56    render_window.draw(shape);
57    render_window.draw(text);
58}
examples/borrowed-resources.rs (line 56)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "Borrowed resources",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Create a new texture. (Hey Frank!)
24    let frank = Texture::from_file("frank.jpeg")?;
25
26    // Create a font.
27    let font = Font::from_file("sansation.ttf")?;
28
29    // Create a circle with the Texture.
30    let mut circle = CircleShape::with_texture(&frank);
31    circle.set_radius(70.0);
32    circle.set_position((100.0, 100.0));
33
34    // Create a Sprite.
35    let mut sprite = Sprite::new();
36    // Have it use the same texture as the circle.
37    sprite.set_texture(&frank, true);
38    sprite.set_position((400.0, 300.0));
39    sprite.set_scale(0.5);
40
41    // Create a ConvexShape using the same texture.
42    let mut convex_shape = ConvexShape::with_texture(6, &frank);
43    convex_shape.set_point(0, (400., 100.));
44    convex_shape.set_point(1, (500., 70.));
45    convex_shape.set_point(2, (450., 100.));
46    convex_shape.set_point(3, (580., 150.));
47    convex_shape.set_point(4, (420., 230.));
48    convex_shape.set_point(5, (420., 120.));
49
50    // Create an initialized text using the font.
51    let title = Text::new("Borrowed resources example!", &font, 50);
52
53    // Create a second text using the same font.
54    // This time, we create and initialize it separately.
55    let mut second_text = Text::default();
56    second_text.set_string("This text shares the same font with the title!");
57    second_text.set_font(&font);
58    second_text.set_fill_color(Color::GREEN);
59    second_text.set_position((10.0, 350.0));
60    second_text.set_character_size(20);
61
62    // Create a third text using the same font.
63    let mut third_text = Text::new("This one too!", &font, 20);
64    third_text.set_position((300.0, 100.0));
65    third_text.set_fill_color(Color::RED);
66
67    'mainloop: loop {
68        while let Some(event) = window.poll_event() {
69            match event {
70                Event::Closed
71                | Event::KeyPressed {
72                    code: Key::Escape, ..
73                } => break 'mainloop,
74                _ => {}
75            }
76        }
77
78        window.clear(Color::BLACK);
79        window.draw(&circle);
80        window.draw(&sprite);
81        window.draw(&convex_shape);
82        window.draw(&title);
83        window.draw(&second_text);
84        window.draw(&third_text);
85
86        // Little test here for `Shape::points`
87        let mut circ = CircleShape::new(4.0, 30);
88        circ.set_origin(2.0);
89        circ.set_fill_color(Color::YELLOW);
90
91        for p in convex_shape.points() {
92            circ.set_position(p);
93            window.draw(&circ);
94        }
95
96        window.display();
97    }
98    Ok(())
99}
examples/shader.rs (line 308)
258fn main() -> SfResult<()> {
259    example_ensure_right_working_dir();
260
261    let mut window = RenderWindow::new(
262        (800, 600),
263        "SFML Shader",
264        Style::TITLEBAR | Style::CLOSE,
265        &Default::default(),
266    )?;
267    window.set_vertical_sync_enabled(true);
268    let font = Font::from_file("sansation.ttf")?;
269    let bg = Texture::from_file("background.jpg")?;
270    let mut bg_texture = Texture::from_file("sfml.png")?;
271    bg_texture.set_smooth(true);
272    let mut entity_texture = Texture::from_file("devices.png")?;
273    entity_texture.set_smooth(true);
274    let effects: [&mut dyn Effect; 4] = [
275        &mut Pixelate::new(&bg)?,
276        &mut WaveBlur::new(&font)?,
277        &mut StormBlink::new()?,
278        &mut Edge::new(&bg_texture, &entity_texture)?,
279    ];
280    let mut current = 0;
281    let text_bg_texture = Texture::from_file("text-background.png")?;
282    let mut text_bg = Sprite::with_texture(&text_bg_texture);
283    text_bg.set_position((0., 520.));
284    text_bg.set_color(Color::rgba(255, 255, 255, 200));
285    let msg = format!("Current effect: {}", effects[current].name());
286    let mut desc = Text::new(&msg, &font, 20);
287    desc.set_position((10., 530.));
288    desc.set_fill_color(Color::rgb(80, 80, 80));
289    let msg = "Press left and right arrows to change the current shader";
290    let mut instructions = Text::new(msg, &font, 20);
291    instructions.set_position((280., 555.));
292    instructions.set_fill_color(Color::rgb(80, 80, 80));
293    let clock = Clock::start()?;
294
295    while window.is_open() {
296        while let Some(event) = window.poll_event() {
297            use crate::Event::*;
298            match event {
299                Closed => window.close(),
300                KeyPressed { code, .. } => match code {
301                    Key::Escape => window.close(),
302                    Key::Left => {
303                        if current == 0 {
304                            current = effects.len() - 1;
305                        } else {
306                            current -= 1;
307                        }
308                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
309                    }
310                    Key::Right => {
311                        if current == effects.len() - 1 {
312                            current = 0;
313                        } else {
314                            current += 1;
315                        }
316                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
317                    }
318                    _ => {}
319                },
320                _ => {}
321            }
322        }
323
324        let x = window.mouse_position().x as f32 / window.size().x as f32;
325        let y = window.mouse_position().y as f32 / window.size().y as f32;
326
327        effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
328
329        window.clear(Color::rgb(255, 128, 0));
330        window.draw(effects[current].as_drawable());
331        window.draw(&text_bg);
332        window.draw(&instructions);
333        window.draw(&desc);
334        window.display();
335    }
336    Ok(())
337}
examples/mouse.rs (lines 71-78)
5fn main() -> SfResult<()> {
6    example_ensure_right_working_dir();
7
8    let mut window = RenderWindow::new(
9        (800, 600),
10        "Mouse events",
11        Style::CLOSE,
12        &Default::default(),
13    )?;
14    window.set_mouse_cursor_visible(false);
15    window.set_vertical_sync_enabled(true);
16
17    let font = Font::from_file("sansation.ttf")?;
18    let mut circle = CircleShape::new(4., 30);
19    let mut texts: Vec<Text> = Vec::new();
20    let mut mp_text = Text::new("", &font, 14);
21    let mut cursor_visible = false;
22    let mut grabbed = false;
23    macro_rules! push_text {
24        ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25            let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26            text.set_position(($x as f32, $y as f32));
27            texts.push(text);
28        }
29    }
30
31    'mainloop: loop {
32        while let Some(ev) = window.poll_event() {
33            match ev {
34                Event::Closed => break 'mainloop,
35                Event::MouseWheelScrolled { wheel, delta, x, y } => {
36                    push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37                }
38                Event::MouseButtonPressed { button, x, y } => {
39                    push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40                }
41                Event::MouseButtonReleased { button, x, y } => {
42                    push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43                }
44                Event::KeyPressed { code, .. } => {
45                    if code == Key::W {
46                        window.set_mouse_position(Vector2i::new(400, 300));
47                    } else if code == Key::D {
48                        let dm = VideoMode::desktop_mode();
49                        let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50                        mouse::set_desktop_position(center);
51                    } else if code == Key::V {
52                        cursor_visible = !cursor_visible;
53                        window.set_mouse_cursor_visible(cursor_visible);
54                    } else if code == Key::G {
55                        grabbed = !grabbed;
56                        window.set_mouse_cursor_grabbed(grabbed);
57                    }
58                }
59                _ => {}
60            }
61        }
62
63        let mp = window.mouse_position();
64        let dmp = mouse::desktop_position();
65        let cur_vis_msg = if cursor_visible {
66            "visible"
67        } else {
68            "invisible"
69        };
70        let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71        mp_text.set_string(&format!(
72            "x: {}, y: {} (Window)\n\
73             x: {}, y: {} (Desktop)\n\
74             [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75             'W' to center mouse on window\n\
76             'D' to center mouse on desktop",
77            mp.x, mp.y, dmp.x, dmp.y
78        ));
79
80        circle.set_position((mp.x as f32, mp.y as f32));
81
82        window.clear(Color::BLACK);
83        // Push texts out of each other's way
84        for i in (0..texts.len()).rev() {
85            for j in (0..i).rev() {
86                if let Some(intersect) = texts[i]
87                    .global_bounds()
88                    .intersection(&texts[j].global_bounds())
89                {
90                    texts[j].move_((0., -intersect.height));
91                }
92            }
93        }
94        texts.retain(|txt| txt.fill_color().a > 0);
95        for txt in &mut texts {
96            let mut color = txt.fill_color();
97            color.a -= 1;
98            txt.set_fill_color(color);
99            window.draw(txt);
100        }
101        if !cursor_visible {
102            window.draw(&circle);
103        }
104        window.draw(&mp_text);
105        window.display();
106    }
107    Ok(())
108}
examples/window-test.rs (lines 85-88)
13fn main() -> SfResult<()> {
14    let configs = [
15        WindowConfig {
16            mode: (320, 240),
17            title: "(Windowed) Retro",
18            style: Style::CLOSE,
19        },
20        WindowConfig {
21            mode: (640, 480),
22            title: "(Windowed) Classic",
23            style: Style::DEFAULT,
24        },
25        WindowConfig {
26            mode: (800, 600),
27            title: "(Windowed) Big",
28            style: Style::TITLEBAR,
29        },
30    ];
31    let mut cfg_idx = 2usize;
32    let mut rw = RenderWindow::new(
33        configs[cfg_idx].mode,
34        "Window test",
35        Style::CLOSE,
36        &ContextSettings::default(),
37    )?;
38    let font = Font::from_memory_static(include_bytes!("resources/sansation.ttf"))?;
39    let fs_modes = VideoMode::fullscreen_modes();
40
41    while rw.is_open() {
42        while let Some(ev) = rw.poll_event() {
43            match ev {
44                Event::Closed => rw.close(),
45                Event::KeyPressed { code, .. } => match code {
46                    Key::Up => cfg_idx = cfg_idx.saturating_sub(1),
47                    Key::Down => {
48                        if cfg_idx + 1 < configs.len() + fs_modes.len() {
49                            cfg_idx += 1
50                        }
51                    }
52                    Key::Enter => match configs.get(cfg_idx) {
53                        Some(cfg) => {
54                            rw.recreate(cfg.mode, cfg.title, cfg.style, &ContextSettings::default())
55                        }
56                        None => match fs_modes.get(cfg_idx - configs.len()) {
57                            Some(mode) => rw.recreate(
58                                *mode,
59                                "Fullscreen",
60                                Style::FULLSCREEN,
61                                &ContextSettings::default(),
62                            ),
63                            None => {
64                                eprintln!("Invalid index: {cfg_idx}");
65                            }
66                        },
67                    },
68                    _ => {}
69                },
70                _ => {}
71            }
72        }
73        rw.clear(Color::BLACK);
74        let fontsize = 16;
75        let mut txt = Text::new("Arrow keys to select mode, enter to set.", &font, fontsize);
76        rw.draw(&txt);
77        let mut y = fontsize as f32;
78        for (i, cfg) in configs.iter().enumerate() {
79            let fc = if i == cfg_idx {
80                Color::YELLOW
81            } else {
82                Color::WHITE
83            };
84            txt.set_fill_color(fc);
85            txt.set_string(&format!(
86                "{}x{} \"{}\" ({:?})",
87                cfg.mode.0, cfg.mode.1, cfg.title, cfg.style
88            ));
89            txt.set_position((0., y));
90            rw.draw(&txt);
91            y += fontsize as f32;
92        }
93        let mut i = configs.len();
94        y += fontsize as f32;
95        txt.set_position((0., y));
96        txt.set_fill_color(Color::WHITE);
97        txt.set_string("= Fullscreen modes =");
98        rw.draw(&txt);
99        for mode in fs_modes.iter() {
100            let n_rows = 23;
101            let column = i / n_rows;
102            let row = i % n_rows;
103            let fc = if i == cfg_idx {
104                Color::YELLOW
105            } else {
106                Color::WHITE
107            };
108            txt.set_fill_color(fc);
109            let left_pad = 16.0;
110            let x = left_pad + (column * 128) as f32;
111            let gap = 16.0;
112            let y = y + gap + (row * fontsize as usize) as f32;
113            txt.set_position((x, y));
114            txt.set_string(&format!(
115                "{}x{}x{}",
116                mode.width, mode.height, mode.bits_per_pixel
117            ));
118            rw.draw(&txt);
119            i += 1;
120        }
121        rw.display();
122    }
123    Ok(())
124}
Source

pub fn string(&self) -> &SfStr

Get the string of a text

Examples found in repository?
examples/unicode-text-entry.rs (line 73)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn character_size(&self) -> u32

Get the size of the characters

Return the size of the characters

Source

pub fn set_font(&mut self, font: &'s Font)

Set the font of the text

The font argument refers to a texture that must exist as long as the text uses it. Indeed, the text doesn’t store its own copy of the font, but rather keeps a pointer to the one that you passed to this function. If the font is destroyed and the text tries to use it, the behaviour is undefined.

font - New font

Examples found in repository?
examples/borrowed-resources.rs (line 57)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "Borrowed resources",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Create a new texture. (Hey Frank!)
24    let frank = Texture::from_file("frank.jpeg")?;
25
26    // Create a font.
27    let font = Font::from_file("sansation.ttf")?;
28
29    // Create a circle with the Texture.
30    let mut circle = CircleShape::with_texture(&frank);
31    circle.set_radius(70.0);
32    circle.set_position((100.0, 100.0));
33
34    // Create a Sprite.
35    let mut sprite = Sprite::new();
36    // Have it use the same texture as the circle.
37    sprite.set_texture(&frank, true);
38    sprite.set_position((400.0, 300.0));
39    sprite.set_scale(0.5);
40
41    // Create a ConvexShape using the same texture.
42    let mut convex_shape = ConvexShape::with_texture(6, &frank);
43    convex_shape.set_point(0, (400., 100.));
44    convex_shape.set_point(1, (500., 70.));
45    convex_shape.set_point(2, (450., 100.));
46    convex_shape.set_point(3, (580., 150.));
47    convex_shape.set_point(4, (420., 230.));
48    convex_shape.set_point(5, (420., 120.));
49
50    // Create an initialized text using the font.
51    let title = Text::new("Borrowed resources example!", &font, 50);
52
53    // Create a second text using the same font.
54    // This time, we create and initialize it separately.
55    let mut second_text = Text::default();
56    second_text.set_string("This text shares the same font with the title!");
57    second_text.set_font(&font);
58    second_text.set_fill_color(Color::GREEN);
59    second_text.set_position((10.0, 350.0));
60    second_text.set_character_size(20);
61
62    // Create a third text using the same font.
63    let mut third_text = Text::new("This one too!", &font, 20);
64    third_text.set_position((300.0, 100.0));
65    third_text.set_fill_color(Color::RED);
66
67    'mainloop: loop {
68        while let Some(event) = window.poll_event() {
69            match event {
70                Event::Closed
71                | Event::KeyPressed {
72                    code: Key::Escape, ..
73                } => break 'mainloop,
74                _ => {}
75            }
76        }
77
78        window.clear(Color::BLACK);
79        window.draw(&circle);
80        window.draw(&sprite);
81        window.draw(&convex_shape);
82        window.draw(&title);
83        window.draw(&second_text);
84        window.draw(&third_text);
85
86        // Little test here for `Shape::points`
87        let mut circ = CircleShape::new(4.0, 30);
88        circ.set_origin(2.0);
89        circ.set_fill_color(Color::YELLOW);
90
91        for p in convex_shape.points() {
92            circ.set_position(p);
93            window.draw(&circ);
94        }
95
96        window.display();
97    }
98    Ok(())
99}
More examples
Hide additional examples
examples/pong.rs (line 92)
21fn main() -> SfResult<()> {
22    example_ensure_right_working_dir();
23
24    let mut rng = thread_rng();
25
26    // Optional antialiasing
27    let mut aa_level = 0;
28
29    if let Some(arg) = env::args().nth(1) {
30        match arg.parse::<u32>() {
31            Ok(arg_as_num) => aa_level = arg_as_num,
32            Err(e) => println!("Didn't set AA level: {e}"),
33        }
34    }
35
36    // Define some constants
37    let game_width = 800;
38    let game_height = 600;
39    let paddle_size = Vector2f::new(25., 100.);
40    let ball_radius = 10.;
41
42    // Create the window of the application
43    let context_settings = ContextSettings {
44        antialiasing_level: aa_level,
45        ..Default::default()
46    };
47    let mut window = RenderWindow::new(
48        (game_width, game_height),
49        "SFML Pong",
50        Style::CLOSE,
51        &context_settings,
52    )?;
53    let context_settings = window.settings();
54    if context_settings.antialiasing_level > 0 {
55        println!("Using {}xAA", context_settings.antialiasing_level);
56    }
57    window.set_vertical_sync_enabled(true);
58
59    // Load the sounds used in the game
60    let ball_soundbuffer = SoundBuffer::from_file("ball.wav")?;
61    let mut ball_sound = Sound::with_buffer(&ball_soundbuffer);
62
63    // Create the left paddle
64    let mut left_paddle = RectangleShape::new();
65    left_paddle.set_size(paddle_size - Vector2f::new(3., 3.));
66    left_paddle.set_outline_thickness(3.);
67    left_paddle.set_outline_color(Color::BLACK);
68    left_paddle.set_fill_color(Color::rgb(100, 100, 200));
69    left_paddle.set_origin(paddle_size / 2.);
70
71    // Create the right paddle
72    let mut right_paddle = RectangleShape::new();
73    right_paddle.set_size(paddle_size - Vector2f::new(3., 3.));
74    right_paddle.set_outline_thickness(3.);
75    right_paddle.set_outline_color(Color::BLACK);
76    right_paddle.set_fill_color(Color::rgb(200, 100, 100));
77    right_paddle.set_origin(paddle_size / 2.);
78
79    // Create the ball
80    let mut ball = CircleShape::default();
81    ball.set_radius(ball_radius - 3.);
82    ball.set_outline_thickness(3.);
83    ball.set_outline_color(Color::BLACK);
84    ball.set_fill_color(Color::WHITE);
85    ball.set_origin(ball_radius / 2.);
86
87    // Load the text font
88    let font = Font::from_file("sansation.ttf")?;
89
90    // Initialize the pause message
91    let mut pause_message = Text::default();
92    pause_message.set_font(&font);
93    pause_message.set_character_size(40);
94    pause_message.set_position((170., 150.));
95    pause_message.set_fill_color(Color::WHITE);
96    pause_message.set_string("Welcome to SFML pong!\nPress space to start the game");
97
98    // Define the paddles properties
99    let mut ai_timer = Clock::start()?;
100    let paddle_speed = 400.;
101    let mut right_paddle_speed = 0.;
102    let mut ball_speed = 400.;
103    let mut ball_angle = 0.;
104
105    let mut clock = Clock::start()?;
106    let mut is_playing = false;
107    let mut up = false;
108    let mut down = false;
109
110    'mainloop: loop {
111        while let Some(event) = window.poll_event() {
112            match event {
113                Event::Closed
114                | Event::KeyPressed {
115                    code: Key::Escape, ..
116                } => break 'mainloop,
117                Event::KeyPressed {
118                    code: Key::Space, ..
119                } if !is_playing => {
120                    // (re)start the game
121                    is_playing = true;
122                    ball_speed = 400.0;
123                    ball_sound.set_pitch(1.0);
124                    clock.restart();
125                    // Reset the position of the paddles and ball
126                    left_paddle.set_position((10. + paddle_size.x / 2., game_height as f32 / 2.));
127                    right_paddle.set_position((
128                        game_width as f32 - 10. - paddle_size.x / 2.,
129                        game_height as f32 / 2.,
130                    ));
131                    ball.set_position((game_width as f32 / 2., game_height as f32 / 2.));
132                    // Reset the ball angle
133                    loop {
134                        // Make sure the ball initial angle is not too much vertical
135                        ball_angle = rng.gen_range(0.0..360.) * 2. * PI / 360.;
136
137                        if ball_angle.cos().abs() >= 0.7 {
138                            break;
139                        }
140                    }
141                }
142                Event::KeyPressed { code: Key::Up, .. }
143                | Event::KeyPressed {
144                    scan: Scancode::W, ..
145                } => up = true,
146                Event::KeyReleased { code: Key::Up, .. }
147                | Event::KeyReleased {
148                    scan: Scancode::W, ..
149                } => up = false,
150                Event::KeyPressed {
151                    code: Key::Down, ..
152                }
153                | Event::KeyPressed {
154                    scan: Scancode::S, ..
155                } => down = true,
156                Event::KeyReleased {
157                    code: Key::Down, ..
158                }
159                | Event::KeyReleased {
160                    scan: Scancode::S, ..
161                } => down = false,
162                _ => {}
163            }
164        }
165        if is_playing {
166            let delta_time = clock.restart().as_seconds();
167
168            // Move the player's paddle
169            if up && (left_paddle.position().y - paddle_size.y / 2. > 5.) {
170                left_paddle.move_((0., -paddle_speed * delta_time));
171            }
172            if down && (left_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.) {
173                left_paddle.move_((0., paddle_speed * delta_time));
174            }
175
176            // Move the computer's paddle
177            if ((right_paddle_speed < 0.) && (right_paddle.position().y - paddle_size.y / 2. > 5.))
178                || ((right_paddle_speed > 0.)
179                    && (right_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.))
180            {
181                right_paddle.move_((0., right_paddle_speed * delta_time));
182            }
183
184            // Update the computer's paddle direction according to the ball position
185            if ai_timer.elapsed_time() > AI_REACT_DELAY {
186                ai_timer.restart();
187                if ball.position().y + ball_radius > right_paddle.position().y + paddle_size.y / 2.
188                {
189                    right_paddle_speed = paddle_speed;
190                } else if ball.position().y - ball_radius
191                    < right_paddle.position().y - paddle_size.y / 2.
192                {
193                    right_paddle_speed = -paddle_speed;
194                } else {
195                    right_paddle_speed = 0.;
196                }
197            }
198
199            // Move the ball
200            let factor = ball_speed * delta_time;
201            ball.move_((ball_angle.cos() * factor, ball_angle.sin() * factor));
202
203            // Check collisions between the ball and the screen
204            if ball.position().x - ball_radius < 0. {
205                is_playing = false;
206                pause_message.set_string("You lost !\nPress space to restart or\nescape to exit");
207            }
208            if ball.position().x + ball_radius > game_width as f32 {
209                is_playing = false;
210                pause_message.set_string("You won !\nPress space to restart or\nescape to exit");
211            }
212            if ball.position().y - ball_radius < 0. {
213                on_bounce(&mut ball_sound, &mut ball_speed);
214                ball_angle = -ball_angle;
215                let p = ball.position().x;
216                ball.set_position((p, ball_radius + 0.1));
217            }
218            if ball.position().y + ball_radius > game_height as f32 {
219                on_bounce(&mut ball_sound, &mut ball_speed);
220                ball_angle = -ball_angle;
221                let p = ball.position().x;
222                ball.set_position((p, game_height as f32 - ball_radius - 0.1));
223            }
224
225            // Check the collisions between the ball and the paddles
226            // Left Paddle
227            let (ball_pos, paddle_pos) = (ball.position(), left_paddle.position());
228            if ball_pos.x - ball_radius < paddle_pos.x + paddle_size.x / 2.
229                && ball_pos.y + ball_radius >= paddle_pos.y - paddle_size.y / 2.
230                && ball_pos.y - ball_radius <= paddle_pos.y + paddle_size.y / 2.
231            {
232                if ball_pos.y > paddle_pos.y {
233                    ball_angle = PI - ball_angle + rng.gen_range(0.0..20.) * PI / 180.;
234                } else {
235                    ball_angle = PI - ball_angle - rng.gen_range(0.0..20.) * PI / 180.;
236                }
237
238                on_bounce(&mut ball_sound, &mut ball_speed);
239                ball.set_position((
240                    paddle_pos.x + ball_radius + paddle_size.x / 2. + 0.1,
241                    ball_pos.y,
242                ));
243            }
244
245            // Right Paddle
246            let (ball_pos, paddle_pos) = (ball.position(), right_paddle.position());
247            if ball_pos.x + ball_radius > paddle_pos.x - paddle_size.x / 2.
248                && ball_pos.y + ball_radius >= paddle_pos.y - paddle_size.y / 2.
249                && ball_pos.y - ball_radius <= paddle_pos.y + paddle_size.y / 2.
250            {
251                if ball_pos.y > paddle_pos.y {
252                    ball_angle = PI - ball_angle + rng.gen_range(0.0..20.) * PI / 180.;
253                } else {
254                    ball_angle = PI - ball_angle - rng.gen_range(0.0..20.) * PI / 180.;
255                }
256
257                on_bounce(&mut ball_sound, &mut ball_speed);
258                ball.set_position((
259                    paddle_pos.x - ball_radius - paddle_size.x / 2. - 0.1,
260                    ball_pos.y,
261                ));
262            }
263        }
264        // Clear the window
265        window.clear(Color::rgb(50, 200, 50));
266
267        if is_playing {
268            // Draw the paddles and the ball
269            window.draw(&left_paddle);
270            window.draw(&right_paddle);
271            window.draw(&ball);
272        } else {
273            // Draw the pause message
274            window.draw(&pause_message);
275        }
276
277        // Display things on screen
278        window.display()
279    }
280    Ok(())
281}
Source

pub fn set_style(&mut self, style: TextStyle)

Set the style of a text

You can pass a combination of one or more styles, for example Bold | Italic. The default style is Regular.

§Arguments
  • style - New style
Examples found in repository?
examples/unicode-text-entry.rs (line 98)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn set_character_size(&mut self, size: u32)

Set the size of the characters of a text

The default size is 30.

§Arguments
  • size - The new character size, in pixels
Examples found in repository?
examples/borrowed-resources.rs (line 60)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "Borrowed resources",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Create a new texture. (Hey Frank!)
24    let frank = Texture::from_file("frank.jpeg")?;
25
26    // Create a font.
27    let font = Font::from_file("sansation.ttf")?;
28
29    // Create a circle with the Texture.
30    let mut circle = CircleShape::with_texture(&frank);
31    circle.set_radius(70.0);
32    circle.set_position((100.0, 100.0));
33
34    // Create a Sprite.
35    let mut sprite = Sprite::new();
36    // Have it use the same texture as the circle.
37    sprite.set_texture(&frank, true);
38    sprite.set_position((400.0, 300.0));
39    sprite.set_scale(0.5);
40
41    // Create a ConvexShape using the same texture.
42    let mut convex_shape = ConvexShape::with_texture(6, &frank);
43    convex_shape.set_point(0, (400., 100.));
44    convex_shape.set_point(1, (500., 70.));
45    convex_shape.set_point(2, (450., 100.));
46    convex_shape.set_point(3, (580., 150.));
47    convex_shape.set_point(4, (420., 230.));
48    convex_shape.set_point(5, (420., 120.));
49
50    // Create an initialized text using the font.
51    let title = Text::new("Borrowed resources example!", &font, 50);
52
53    // Create a second text using the same font.
54    // This time, we create and initialize it separately.
55    let mut second_text = Text::default();
56    second_text.set_string("This text shares the same font with the title!");
57    second_text.set_font(&font);
58    second_text.set_fill_color(Color::GREEN);
59    second_text.set_position((10.0, 350.0));
60    second_text.set_character_size(20);
61
62    // Create a third text using the same font.
63    let mut third_text = Text::new("This one too!", &font, 20);
64    third_text.set_position((300.0, 100.0));
65    third_text.set_fill_color(Color::RED);
66
67    'mainloop: loop {
68        while let Some(event) = window.poll_event() {
69            match event {
70                Event::Closed
71                | Event::KeyPressed {
72                    code: Key::Escape, ..
73                } => break 'mainloop,
74                _ => {}
75            }
76        }
77
78        window.clear(Color::BLACK);
79        window.draw(&circle);
80        window.draw(&sprite);
81        window.draw(&convex_shape);
82        window.draw(&title);
83        window.draw(&second_text);
84        window.draw(&third_text);
85
86        // Little test here for `Shape::points`
87        let mut circ = CircleShape::new(4.0, 30);
88        circ.set_origin(2.0);
89        circ.set_fill_color(Color::YELLOW);
90
91        for p in convex_shape.points() {
92            circ.set_position(p);
93            window.draw(&circ);
94        }
95
96        window.display();
97    }
98    Ok(())
99}
More examples
Hide additional examples
examples/pong.rs (line 93)
21fn main() -> SfResult<()> {
22    example_ensure_right_working_dir();
23
24    let mut rng = thread_rng();
25
26    // Optional antialiasing
27    let mut aa_level = 0;
28
29    if let Some(arg) = env::args().nth(1) {
30        match arg.parse::<u32>() {
31            Ok(arg_as_num) => aa_level = arg_as_num,
32            Err(e) => println!("Didn't set AA level: {e}"),
33        }
34    }
35
36    // Define some constants
37    let game_width = 800;
38    let game_height = 600;
39    let paddle_size = Vector2f::new(25., 100.);
40    let ball_radius = 10.;
41
42    // Create the window of the application
43    let context_settings = ContextSettings {
44        antialiasing_level: aa_level,
45        ..Default::default()
46    };
47    let mut window = RenderWindow::new(
48        (game_width, game_height),
49        "SFML Pong",
50        Style::CLOSE,
51        &context_settings,
52    )?;
53    let context_settings = window.settings();
54    if context_settings.antialiasing_level > 0 {
55        println!("Using {}xAA", context_settings.antialiasing_level);
56    }
57    window.set_vertical_sync_enabled(true);
58
59    // Load the sounds used in the game
60    let ball_soundbuffer = SoundBuffer::from_file("ball.wav")?;
61    let mut ball_sound = Sound::with_buffer(&ball_soundbuffer);
62
63    // Create the left paddle
64    let mut left_paddle = RectangleShape::new();
65    left_paddle.set_size(paddle_size - Vector2f::new(3., 3.));
66    left_paddle.set_outline_thickness(3.);
67    left_paddle.set_outline_color(Color::BLACK);
68    left_paddle.set_fill_color(Color::rgb(100, 100, 200));
69    left_paddle.set_origin(paddle_size / 2.);
70
71    // Create the right paddle
72    let mut right_paddle = RectangleShape::new();
73    right_paddle.set_size(paddle_size - Vector2f::new(3., 3.));
74    right_paddle.set_outline_thickness(3.);
75    right_paddle.set_outline_color(Color::BLACK);
76    right_paddle.set_fill_color(Color::rgb(200, 100, 100));
77    right_paddle.set_origin(paddle_size / 2.);
78
79    // Create the ball
80    let mut ball = CircleShape::default();
81    ball.set_radius(ball_radius - 3.);
82    ball.set_outline_thickness(3.);
83    ball.set_outline_color(Color::BLACK);
84    ball.set_fill_color(Color::WHITE);
85    ball.set_origin(ball_radius / 2.);
86
87    // Load the text font
88    let font = Font::from_file("sansation.ttf")?;
89
90    // Initialize the pause message
91    let mut pause_message = Text::default();
92    pause_message.set_font(&font);
93    pause_message.set_character_size(40);
94    pause_message.set_position((170., 150.));
95    pause_message.set_fill_color(Color::WHITE);
96    pause_message.set_string("Welcome to SFML pong!\nPress space to start the game");
97
98    // Define the paddles properties
99    let mut ai_timer = Clock::start()?;
100    let paddle_speed = 400.;
101    let mut right_paddle_speed = 0.;
102    let mut ball_speed = 400.;
103    let mut ball_angle = 0.;
104
105    let mut clock = Clock::start()?;
106    let mut is_playing = false;
107    let mut up = false;
108    let mut down = false;
109
110    'mainloop: loop {
111        while let Some(event) = window.poll_event() {
112            match event {
113                Event::Closed
114                | Event::KeyPressed {
115                    code: Key::Escape, ..
116                } => break 'mainloop,
117                Event::KeyPressed {
118                    code: Key::Space, ..
119                } if !is_playing => {
120                    // (re)start the game
121                    is_playing = true;
122                    ball_speed = 400.0;
123                    ball_sound.set_pitch(1.0);
124                    clock.restart();
125                    // Reset the position of the paddles and ball
126                    left_paddle.set_position((10. + paddle_size.x / 2., game_height as f32 / 2.));
127                    right_paddle.set_position((
128                        game_width as f32 - 10. - paddle_size.x / 2.,
129                        game_height as f32 / 2.,
130                    ));
131                    ball.set_position((game_width as f32 / 2., game_height as f32 / 2.));
132                    // Reset the ball angle
133                    loop {
134                        // Make sure the ball initial angle is not too much vertical
135                        ball_angle = rng.gen_range(0.0..360.) * 2. * PI / 360.;
136
137                        if ball_angle.cos().abs() >= 0.7 {
138                            break;
139                        }
140                    }
141                }
142                Event::KeyPressed { code: Key::Up, .. }
143                | Event::KeyPressed {
144                    scan: Scancode::W, ..
145                } => up = true,
146                Event::KeyReleased { code: Key::Up, .. }
147                | Event::KeyReleased {
148                    scan: Scancode::W, ..
149                } => up = false,
150                Event::KeyPressed {
151                    code: Key::Down, ..
152                }
153                | Event::KeyPressed {
154                    scan: Scancode::S, ..
155                } => down = true,
156                Event::KeyReleased {
157                    code: Key::Down, ..
158                }
159                | Event::KeyReleased {
160                    scan: Scancode::S, ..
161                } => down = false,
162                _ => {}
163            }
164        }
165        if is_playing {
166            let delta_time = clock.restart().as_seconds();
167
168            // Move the player's paddle
169            if up && (left_paddle.position().y - paddle_size.y / 2. > 5.) {
170                left_paddle.move_((0., -paddle_speed * delta_time));
171            }
172            if down && (left_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.) {
173                left_paddle.move_((0., paddle_speed * delta_time));
174            }
175
176            // Move the computer's paddle
177            if ((right_paddle_speed < 0.) && (right_paddle.position().y - paddle_size.y / 2. > 5.))
178                || ((right_paddle_speed > 0.)
179                    && (right_paddle.position().y + paddle_size.y / 2. < game_height as f32 - 5.))
180            {
181                right_paddle.move_((0., right_paddle_speed * delta_time));
182            }
183
184            // Update the computer's paddle direction according to the ball position
185            if ai_timer.elapsed_time() > AI_REACT_DELAY {
186                ai_timer.restart();
187                if ball.position().y + ball_radius > right_paddle.position().y + paddle_size.y / 2.
188                {
189                    right_paddle_speed = paddle_speed;
190                } else if ball.position().y - ball_radius
191                    < right_paddle.position().y - paddle_size.y / 2.
192                {
193                    right_paddle_speed = -paddle_speed;
194                } else {
195                    right_paddle_speed = 0.;
196                }
197            }
198
199            // Move the ball
200            let factor = ball_speed * delta_time;
201            ball.move_((ball_angle.cos() * factor, ball_angle.sin() * factor));
202
203            // Check collisions between the ball and the screen
204            if ball.position().x - ball_radius < 0. {
205                is_playing = false;
206                pause_message.set_string("You lost !\nPress space to restart or\nescape to exit");
207            }
208            if ball.position().x + ball_radius > game_width as f32 {
209                is_playing = false;
210                pause_message.set_string("You won !\nPress space to restart or\nescape to exit");
211            }
212            if ball.position().y - ball_radius < 0. {
213                on_bounce(&mut ball_sound, &mut ball_speed);
214                ball_angle = -ball_angle;
215                let p = ball.position().x;
216                ball.set_position((p, ball_radius + 0.1));
217            }
218            if ball.position().y + ball_radius > game_height as f32 {
219                on_bounce(&mut ball_sound, &mut ball_speed);
220                ball_angle = -ball_angle;
221                let p = ball.position().x;
222                ball.set_position((p, game_height as f32 - ball_radius - 0.1));
223            }
224
225            // Check the collisions between the ball and the paddles
226            // Left Paddle
227            let (ball_pos, paddle_pos) = (ball.position(), left_paddle.position());
228            if ball_pos.x - ball_radius < paddle_pos.x + paddle_size.x / 2.
229                && ball_pos.y + ball_radius >= paddle_pos.y - paddle_size.y / 2.
230                && ball_pos.y - ball_radius <= paddle_pos.y + paddle_size.y / 2.
231            {
232                if ball_pos.y > paddle_pos.y {
233                    ball_angle = PI - ball_angle + rng.gen_range(0.0..20.) * PI / 180.;
234                } else {
235                    ball_angle = PI - ball_angle - rng.gen_range(0.0..20.) * PI / 180.;
236                }
237
238                on_bounce(&mut ball_sound, &mut ball_speed);
239                ball.set_position((
240                    paddle_pos.x + ball_radius + paddle_size.x / 2. + 0.1,
241                    ball_pos.y,
242                ));
243            }
244
245            // Right Paddle
246            let (ball_pos, paddle_pos) = (ball.position(), right_paddle.position());
247            if ball_pos.x + ball_radius > paddle_pos.x - paddle_size.x / 2.
248                && ball_pos.y + ball_radius >= paddle_pos.y - paddle_size.y / 2.
249                && ball_pos.y - ball_radius <= paddle_pos.y + paddle_size.y / 2.
250            {
251                if ball_pos.y > paddle_pos.y {
252                    ball_angle = PI - ball_angle + rng.gen_range(0.0..20.) * PI / 180.;
253                } else {
254                    ball_angle = PI - ball_angle - rng.gen_range(0.0..20.) * PI / 180.;
255                }
256
257                on_bounce(&mut ball_sound, &mut ball_speed);
258                ball.set_position((
259                    paddle_pos.x - ball_radius - paddle_size.x / 2. - 0.1,
260                    ball_pos.y,
261                ));
262            }
263        }
264        // Clear the window
265        window.clear(Color::rgb(50, 200, 50));
266
267        if is_playing {
268            // Draw the paddles and the ball
269            window.draw(&left_paddle);
270            window.draw(&right_paddle);
271            window.draw(&ball);
272        } else {
273            // Draw the pause message
274            window.draw(&pause_message);
275        }
276
277        // Display things on screen
278        window.display()
279    }
280    Ok(())
281}
Source

pub fn style(&self) -> TextStyle

Get the style of a text

Return the current string style (see Style enum)

Examples found in repository?
examples/unicode-text-entry.rs (line 114)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn font(&self) -> Option<&'s Font>

Get the font of a text If the text has no font attached, a None is returned. The returned pointer is const, which means that you can’t modify the font when you retrieve it with this function.

Source

pub fn set_fill_color(&mut self, color: Color)

Set the fill color of the text.

By default, the text’s fill color is opaque white. Setting the fill color to a transparent color with an outline will cause the outline to be displayed in the fill area of the text.

Examples found in repository?
examples/cursor.rs (line 54)
35fn draw_button(
36    rect: &Rect<i32>,
37    shape: &mut RectangleShape,
38    text: &mut Text,
39    string: &str,
40    render_window: &mut RenderWindow,
41    style: ButtonStyle,
42) {
43    shape.set_position((rect.left as f32, rect.top as f32));
44    shape.set_size((rect.width as f32, rect.height as f32));
45    let (rect_fill, rect_outline, text_fill) = match style {
46        ButtonStyle::Normal => (Color::TRANSPARENT, Color::WHITE, Color::WHITE),
47        ButtonStyle::Highlighted => (Color::WHITE, Color::WHITE, Color::BLACK),
48        ButtonStyle::Selected => (Color::GREEN, Color::GREEN, Color::BLACK),
49        ButtonStyle::Error => (Color::RED, Color::BLACK, Color::BLACK),
50    };
51    shape.set_outline_color(rect_outline);
52    shape.set_fill_color(rect_fill);
53    text.set_position((rect.left as f32 + 12.0, rect.top as f32 + 8.0));
54    text.set_fill_color(text_fill);
55    text.set_string(string);
56    render_window.draw(shape);
57    render_window.draw(text);
58}
More examples
Hide additional examples
examples/borrowed-resources.rs (line 58)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "Borrowed resources",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Create a new texture. (Hey Frank!)
24    let frank = Texture::from_file("frank.jpeg")?;
25
26    // Create a font.
27    let font = Font::from_file("sansation.ttf")?;
28
29    // Create a circle with the Texture.
30    let mut circle = CircleShape::with_texture(&frank);
31    circle.set_radius(70.0);
32    circle.set_position((100.0, 100.0));
33
34    // Create a Sprite.
35    let mut sprite = Sprite::new();
36    // Have it use the same texture as the circle.
37    sprite.set_texture(&frank, true);
38    sprite.set_position((400.0, 300.0));
39    sprite.set_scale(0.5);
40
41    // Create a ConvexShape using the same texture.
42    let mut convex_shape = ConvexShape::with_texture(6, &frank);
43    convex_shape.set_point(0, (400., 100.));
44    convex_shape.set_point(1, (500., 70.));
45    convex_shape.set_point(2, (450., 100.));
46    convex_shape.set_point(3, (580., 150.));
47    convex_shape.set_point(4, (420., 230.));
48    convex_shape.set_point(5, (420., 120.));
49
50    // Create an initialized text using the font.
51    let title = Text::new("Borrowed resources example!", &font, 50);
52
53    // Create a second text using the same font.
54    // This time, we create and initialize it separately.
55    let mut second_text = Text::default();
56    second_text.set_string("This text shares the same font with the title!");
57    second_text.set_font(&font);
58    second_text.set_fill_color(Color::GREEN);
59    second_text.set_position((10.0, 350.0));
60    second_text.set_character_size(20);
61
62    // Create a third text using the same font.
63    let mut third_text = Text::new("This one too!", &font, 20);
64    third_text.set_position((300.0, 100.0));
65    third_text.set_fill_color(Color::RED);
66
67    'mainloop: loop {
68        while let Some(event) = window.poll_event() {
69            match event {
70                Event::Closed
71                | Event::KeyPressed {
72                    code: Key::Escape, ..
73                } => break 'mainloop,
74                _ => {}
75            }
76        }
77
78        window.clear(Color::BLACK);
79        window.draw(&circle);
80        window.draw(&sprite);
81        window.draw(&convex_shape);
82        window.draw(&title);
83        window.draw(&second_text);
84        window.draw(&third_text);
85
86        // Little test here for `Shape::points`
87        let mut circ = CircleShape::new(4.0, 30);
88        circ.set_origin(2.0);
89        circ.set_fill_color(Color::YELLOW);
90
91        for p in convex_shape.points() {
92            circ.set_position(p);
93            window.draw(&circ);
94        }
95
96        window.display();
97    }
98    Ok(())
99}
examples/shader.rs (line 288)
258fn main() -> SfResult<()> {
259    example_ensure_right_working_dir();
260
261    let mut window = RenderWindow::new(
262        (800, 600),
263        "SFML Shader",
264        Style::TITLEBAR | Style::CLOSE,
265        &Default::default(),
266    )?;
267    window.set_vertical_sync_enabled(true);
268    let font = Font::from_file("sansation.ttf")?;
269    let bg = Texture::from_file("background.jpg")?;
270    let mut bg_texture = Texture::from_file("sfml.png")?;
271    bg_texture.set_smooth(true);
272    let mut entity_texture = Texture::from_file("devices.png")?;
273    entity_texture.set_smooth(true);
274    let effects: [&mut dyn Effect; 4] = [
275        &mut Pixelate::new(&bg)?,
276        &mut WaveBlur::new(&font)?,
277        &mut StormBlink::new()?,
278        &mut Edge::new(&bg_texture, &entity_texture)?,
279    ];
280    let mut current = 0;
281    let text_bg_texture = Texture::from_file("text-background.png")?;
282    let mut text_bg = Sprite::with_texture(&text_bg_texture);
283    text_bg.set_position((0., 520.));
284    text_bg.set_color(Color::rgba(255, 255, 255, 200));
285    let msg = format!("Current effect: {}", effects[current].name());
286    let mut desc = Text::new(&msg, &font, 20);
287    desc.set_position((10., 530.));
288    desc.set_fill_color(Color::rgb(80, 80, 80));
289    let msg = "Press left and right arrows to change the current shader";
290    let mut instructions = Text::new(msg, &font, 20);
291    instructions.set_position((280., 555.));
292    instructions.set_fill_color(Color::rgb(80, 80, 80));
293    let clock = Clock::start()?;
294
295    while window.is_open() {
296        while let Some(event) = window.poll_event() {
297            use crate::Event::*;
298            match event {
299                Closed => window.close(),
300                KeyPressed { code, .. } => match code {
301                    Key::Escape => window.close(),
302                    Key::Left => {
303                        if current == 0 {
304                            current = effects.len() - 1;
305                        } else {
306                            current -= 1;
307                        }
308                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
309                    }
310                    Key::Right => {
311                        if current == effects.len() - 1 {
312                            current = 0;
313                        } else {
314                            current += 1;
315                        }
316                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
317                    }
318                    _ => {}
319                },
320                _ => {}
321            }
322        }
323
324        let x = window.mouse_position().x as f32 / window.size().x as f32;
325        let y = window.mouse_position().y as f32 / window.size().y as f32;
326
327        effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
328
329        window.clear(Color::rgb(255, 128, 0));
330        window.draw(effects[current].as_drawable());
331        window.draw(&text_bg);
332        window.draw(&instructions);
333        window.draw(&desc);
334        window.display();
335    }
336    Ok(())
337}
examples/mouse.rs (line 98)
5fn main() -> SfResult<()> {
6    example_ensure_right_working_dir();
7
8    let mut window = RenderWindow::new(
9        (800, 600),
10        "Mouse events",
11        Style::CLOSE,
12        &Default::default(),
13    )?;
14    window.set_mouse_cursor_visible(false);
15    window.set_vertical_sync_enabled(true);
16
17    let font = Font::from_file("sansation.ttf")?;
18    let mut circle = CircleShape::new(4., 30);
19    let mut texts: Vec<Text> = Vec::new();
20    let mut mp_text = Text::new("", &font, 14);
21    let mut cursor_visible = false;
22    let mut grabbed = false;
23    macro_rules! push_text {
24        ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25            let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26            text.set_position(($x as f32, $y as f32));
27            texts.push(text);
28        }
29    }
30
31    'mainloop: loop {
32        while let Some(ev) = window.poll_event() {
33            match ev {
34                Event::Closed => break 'mainloop,
35                Event::MouseWheelScrolled { wheel, delta, x, y } => {
36                    push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37                }
38                Event::MouseButtonPressed { button, x, y } => {
39                    push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40                }
41                Event::MouseButtonReleased { button, x, y } => {
42                    push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43                }
44                Event::KeyPressed { code, .. } => {
45                    if code == Key::W {
46                        window.set_mouse_position(Vector2i::new(400, 300));
47                    } else if code == Key::D {
48                        let dm = VideoMode::desktop_mode();
49                        let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50                        mouse::set_desktop_position(center);
51                    } else if code == Key::V {
52                        cursor_visible = !cursor_visible;
53                        window.set_mouse_cursor_visible(cursor_visible);
54                    } else if code == Key::G {
55                        grabbed = !grabbed;
56                        window.set_mouse_cursor_grabbed(grabbed);
57                    }
58                }
59                _ => {}
60            }
61        }
62
63        let mp = window.mouse_position();
64        let dmp = mouse::desktop_position();
65        let cur_vis_msg = if cursor_visible {
66            "visible"
67        } else {
68            "invisible"
69        };
70        let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71        mp_text.set_string(&format!(
72            "x: {}, y: {} (Window)\n\
73             x: {}, y: {} (Desktop)\n\
74             [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75             'W' to center mouse on window\n\
76             'D' to center mouse on desktop",
77            mp.x, mp.y, dmp.x, dmp.y
78        ));
79
80        circle.set_position((mp.x as f32, mp.y as f32));
81
82        window.clear(Color::BLACK);
83        // Push texts out of each other's way
84        for i in (0..texts.len()).rev() {
85            for j in (0..i).rev() {
86                if let Some(intersect) = texts[i]
87                    .global_bounds()
88                    .intersection(&texts[j].global_bounds())
89                {
90                    texts[j].move_((0., -intersect.height));
91                }
92            }
93        }
94        texts.retain(|txt| txt.fill_color().a > 0);
95        for txt in &mut texts {
96            let mut color = txt.fill_color();
97            color.a -= 1;
98            txt.set_fill_color(color);
99            window.draw(txt);
100        }
101        if !cursor_visible {
102            window.draw(&circle);
103        }
104        window.draw(&mp_text);
105        window.display();
106    }
107    Ok(())
108}
examples/window-test.rs (line 84)
13fn main() -> SfResult<()> {
14    let configs = [
15        WindowConfig {
16            mode: (320, 240),
17            title: "(Windowed) Retro",
18            style: Style::CLOSE,
19        },
20        WindowConfig {
21            mode: (640, 480),
22            title: "(Windowed) Classic",
23            style: Style::DEFAULT,
24        },
25        WindowConfig {
26            mode: (800, 600),
27            title: "(Windowed) Big",
28            style: Style::TITLEBAR,
29        },
30    ];
31    let mut cfg_idx = 2usize;
32    let mut rw = RenderWindow::new(
33        configs[cfg_idx].mode,
34        "Window test",
35        Style::CLOSE,
36        &ContextSettings::default(),
37    )?;
38    let font = Font::from_memory_static(include_bytes!("resources/sansation.ttf"))?;
39    let fs_modes = VideoMode::fullscreen_modes();
40
41    while rw.is_open() {
42        while let Some(ev) = rw.poll_event() {
43            match ev {
44                Event::Closed => rw.close(),
45                Event::KeyPressed { code, .. } => match code {
46                    Key::Up => cfg_idx = cfg_idx.saturating_sub(1),
47                    Key::Down => {
48                        if cfg_idx + 1 < configs.len() + fs_modes.len() {
49                            cfg_idx += 1
50                        }
51                    }
52                    Key::Enter => match configs.get(cfg_idx) {
53                        Some(cfg) => {
54                            rw.recreate(cfg.mode, cfg.title, cfg.style, &ContextSettings::default())
55                        }
56                        None => match fs_modes.get(cfg_idx - configs.len()) {
57                            Some(mode) => rw.recreate(
58                                *mode,
59                                "Fullscreen",
60                                Style::FULLSCREEN,
61                                &ContextSettings::default(),
62                            ),
63                            None => {
64                                eprintln!("Invalid index: {cfg_idx}");
65                            }
66                        },
67                    },
68                    _ => {}
69                },
70                _ => {}
71            }
72        }
73        rw.clear(Color::BLACK);
74        let fontsize = 16;
75        let mut txt = Text::new("Arrow keys to select mode, enter to set.", &font, fontsize);
76        rw.draw(&txt);
77        let mut y = fontsize as f32;
78        for (i, cfg) in configs.iter().enumerate() {
79            let fc = if i == cfg_idx {
80                Color::YELLOW
81            } else {
82                Color::WHITE
83            };
84            txt.set_fill_color(fc);
85            txt.set_string(&format!(
86                "{}x{} \"{}\" ({:?})",
87                cfg.mode.0, cfg.mode.1, cfg.title, cfg.style
88            ));
89            txt.set_position((0., y));
90            rw.draw(&txt);
91            y += fontsize as f32;
92        }
93        let mut i = configs.len();
94        y += fontsize as f32;
95        txt.set_position((0., y));
96        txt.set_fill_color(Color::WHITE);
97        txt.set_string("= Fullscreen modes =");
98        rw.draw(&txt);
99        for mode in fs_modes.iter() {
100            let n_rows = 23;
101            let column = i / n_rows;
102            let row = i % n_rows;
103            let fc = if i == cfg_idx {
104                Color::YELLOW
105            } else {
106                Color::WHITE
107            };
108            txt.set_fill_color(fc);
109            let left_pad = 16.0;
110            let x = left_pad + (column * 128) as f32;
111            let gap = 16.0;
112            let y = y + gap + (row * fontsize as usize) as f32;
113            txt.set_position((x, y));
114            txt.set_string(&format!(
115                "{}x{}x{}",
116                mode.width, mode.height, mode.bits_per_pixel
117            ));
118            rw.draw(&txt);
119            i += 1;
120        }
121        rw.display();
122    }
123    Ok(())
124}
examples/unicode-text-entry.rs (line 33)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn set_outline_color(&mut self, color: Color)

Set the outline color of the text.

By default, the text’s outline color is opaque black.

Examples found in repository?
examples/spritemark.rs (line 77)
62fn main() -> SfResult<()> {
63    example_ensure_right_working_dir();
64
65    let native_mode = VideoMode::desktop_mode();
66    let mut window = RenderWindow::new(
67        native_mode,
68        "Spritemark",
69        Style::default(),
70        &ContextSettings::default(),
71    )?;
72    window.set_position(Vector2::new(0, 0));
73    window.set_vertical_sync_enabled(true);
74    let font = Font::from_file("sansation.ttf")?;
75    let texture = Texture::from_file("devices.png")?;
76    let mut text = Text::new("", &font, 18);
77    text.set_outline_color(Color::BLACK);
78    text.set_outline_thickness(1.0);
79    let mut click_counter = 0;
80    let mut objects = Vec::new();
81    let mut rng = thread_rng();
82    let mut rs = RenderStates::default();
83    let mut buf = Vec::new();
84    let mut frames_rendered = 0;
85    let mut sec_clock = Clock::start()?;
86    let mut fps = 0;
87    let mut lmb_down = false;
88    let mut view = View::new()?;
89
90    while window.is_open() {
91        while let Some(event) = window.poll_event() {
92            match event {
93                Event::Closed
94                | Event::KeyPressed {
95                    code: Key::Escape, ..
96                } => window.close(),
97                Event::MouseButtonPressed {
98                    button: Button::Left,
99                    ..
100                } => {
101                    click_counter += 1;
102                    lmb_down = true;
103                }
104                Event::MouseButtonReleased {
105                    button: Button::Left,
106                    ..
107                } => {
108                    lmb_down = false;
109                }
110                Event::Resized { width, height } => {
111                    view.reset(Rect::new(0., 0., width as f32, height as f32));
112                    window.set_view(&view);
113                }
114                _ => {}
115            }
116        }
117
118        if lmb_down {
119            let mp = window.mouse_position();
120            for _ in 0..25 {
121                objects.push(Object {
122                    position: fconv(mp),
123                    speed: Vector2f::new(rng.gen_range(-3.0..3.0), 0.0),
124                    image_id: click_counter % N_IMAGES,
125                    angle: 0.0,
126                    rot_speed: rng.gen_range(-2.0..2.0),
127                });
128            }
129        }
130
131        for obj in &mut objects {
132            let size = f32::from(SUBIMAGE_SIZE);
133            let tex_x = f32::from(obj.image_id) * size;
134            let mut tf = Transform::default();
135            tf.translate(obj.position.x, obj.position.y);
136            tf.rotate_with_center(obj.angle, size / 2.0, size / 2.0);
137            buf.push(Vertex {
138                color: Color::WHITE,
139                position: tf.transform_point(Vector2f::new(0., 0.)),
140                tex_coords: Vector2f::new(tex_x, 0.),
141            });
142            buf.push(Vertex {
143                color: Color::WHITE,
144                position: tf.transform_point(Vector2f::new(0., size)),
145                tex_coords: Vector2f::new(tex_x, size),
146            });
147            buf.push(Vertex {
148                color: Color::WHITE,
149                position: tf.transform_point(Vector2f::new(size, size)),
150                tex_coords: Vector2f::new(tex_x + size, size),
151            });
152            buf.push(Vertex {
153                color: Color::WHITE,
154                position: tf.transform_point(Vector2f::new(size, 0.)),
155                tex_coords: Vector2f::new(tex_x + size, 0.),
156            });
157            obj.update(window.size().y as f32, window.size().x as f32);
158        }
159        window.clear(Color::BLACK);
160        rs.texture = Some(&texture);
161        window.draw_primitives(&buf, PrimitiveType::QUADS, &rs);
162        rs.texture = None;
163        text.set_string(&format!("{} sprites\n{fps} fps", objects.len()));
164        window.draw_text(&text, &rs);
165        window.display();
166        buf.clear();
167        frames_rendered += 1;
168        if sec_clock.elapsed_time().as_milliseconds() >= 1000 {
169            fps = frames_rendered;
170            sec_clock.restart();
171            frames_rendered = 0;
172        }
173    }
174    Ok(())
175}
More examples
Hide additional examples
examples/unicode-text-entry.rs (line 34)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn set_outline_thickness(&mut self, thickness: f32)

Set the thickness of the text’s outline.

By default, the outline thickness is 0.

Be aware that using a negative value for the outline thickness will cause distorted rendering.

Examples found in repository?
examples/spritemark.rs (line 78)
62fn main() -> SfResult<()> {
63    example_ensure_right_working_dir();
64
65    let native_mode = VideoMode::desktop_mode();
66    let mut window = RenderWindow::new(
67        native_mode,
68        "Spritemark",
69        Style::default(),
70        &ContextSettings::default(),
71    )?;
72    window.set_position(Vector2::new(0, 0));
73    window.set_vertical_sync_enabled(true);
74    let font = Font::from_file("sansation.ttf")?;
75    let texture = Texture::from_file("devices.png")?;
76    let mut text = Text::new("", &font, 18);
77    text.set_outline_color(Color::BLACK);
78    text.set_outline_thickness(1.0);
79    let mut click_counter = 0;
80    let mut objects = Vec::new();
81    let mut rng = thread_rng();
82    let mut rs = RenderStates::default();
83    let mut buf = Vec::new();
84    let mut frames_rendered = 0;
85    let mut sec_clock = Clock::start()?;
86    let mut fps = 0;
87    let mut lmb_down = false;
88    let mut view = View::new()?;
89
90    while window.is_open() {
91        while let Some(event) = window.poll_event() {
92            match event {
93                Event::Closed
94                | Event::KeyPressed {
95                    code: Key::Escape, ..
96                } => window.close(),
97                Event::MouseButtonPressed {
98                    button: Button::Left,
99                    ..
100                } => {
101                    click_counter += 1;
102                    lmb_down = true;
103                }
104                Event::MouseButtonReleased {
105                    button: Button::Left,
106                    ..
107                } => {
108                    lmb_down = false;
109                }
110                Event::Resized { width, height } => {
111                    view.reset(Rect::new(0., 0., width as f32, height as f32));
112                    window.set_view(&view);
113                }
114                _ => {}
115            }
116        }
117
118        if lmb_down {
119            let mp = window.mouse_position();
120            for _ in 0..25 {
121                objects.push(Object {
122                    position: fconv(mp),
123                    speed: Vector2f::new(rng.gen_range(-3.0..3.0), 0.0),
124                    image_id: click_counter % N_IMAGES,
125                    angle: 0.0,
126                    rot_speed: rng.gen_range(-2.0..2.0),
127                });
128            }
129        }
130
131        for obj in &mut objects {
132            let size = f32::from(SUBIMAGE_SIZE);
133            let tex_x = f32::from(obj.image_id) * size;
134            let mut tf = Transform::default();
135            tf.translate(obj.position.x, obj.position.y);
136            tf.rotate_with_center(obj.angle, size / 2.0, size / 2.0);
137            buf.push(Vertex {
138                color: Color::WHITE,
139                position: tf.transform_point(Vector2f::new(0., 0.)),
140                tex_coords: Vector2f::new(tex_x, 0.),
141            });
142            buf.push(Vertex {
143                color: Color::WHITE,
144                position: tf.transform_point(Vector2f::new(0., size)),
145                tex_coords: Vector2f::new(tex_x, size),
146            });
147            buf.push(Vertex {
148                color: Color::WHITE,
149                position: tf.transform_point(Vector2f::new(size, size)),
150                tex_coords: Vector2f::new(tex_x + size, size),
151            });
152            buf.push(Vertex {
153                color: Color::WHITE,
154                position: tf.transform_point(Vector2f::new(size, 0.)),
155                tex_coords: Vector2f::new(tex_x + size, 0.),
156            });
157            obj.update(window.size().y as f32, window.size().x as f32);
158        }
159        window.clear(Color::BLACK);
160        rs.texture = Some(&texture);
161        window.draw_primitives(&buf, PrimitiveType::QUADS, &rs);
162        rs.texture = None;
163        text.set_string(&format!("{} sprites\n{fps} fps", objects.len()));
164        window.draw_text(&text, &rs);
165        window.display();
166        buf.clear();
167        frames_rendered += 1;
168        if sec_clock.elapsed_time().as_milliseconds() >= 1000 {
169            fps = frames_rendered;
170            sec_clock.restart();
171            frames_rendered = 0;
172        }
173    }
174    Ok(())
175}
More examples
Hide additional examples
examples/unicode-text-entry.rs (line 35)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn fill_color(&self) -> Color

Returns the fill color of the text.

Examples found in repository?
examples/mouse.rs (line 94)
5fn main() -> SfResult<()> {
6    example_ensure_right_working_dir();
7
8    let mut window = RenderWindow::new(
9        (800, 600),
10        "Mouse events",
11        Style::CLOSE,
12        &Default::default(),
13    )?;
14    window.set_mouse_cursor_visible(false);
15    window.set_vertical_sync_enabled(true);
16
17    let font = Font::from_file("sansation.ttf")?;
18    let mut circle = CircleShape::new(4., 30);
19    let mut texts: Vec<Text> = Vec::new();
20    let mut mp_text = Text::new("", &font, 14);
21    let mut cursor_visible = false;
22    let mut grabbed = false;
23    macro_rules! push_text {
24        ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25            let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26            text.set_position(($x as f32, $y as f32));
27            texts.push(text);
28        }
29    }
30
31    'mainloop: loop {
32        while let Some(ev) = window.poll_event() {
33            match ev {
34                Event::Closed => break 'mainloop,
35                Event::MouseWheelScrolled { wheel, delta, x, y } => {
36                    push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37                }
38                Event::MouseButtonPressed { button, x, y } => {
39                    push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40                }
41                Event::MouseButtonReleased { button, x, y } => {
42                    push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43                }
44                Event::KeyPressed { code, .. } => {
45                    if code == Key::W {
46                        window.set_mouse_position(Vector2i::new(400, 300));
47                    } else if code == Key::D {
48                        let dm = VideoMode::desktop_mode();
49                        let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50                        mouse::set_desktop_position(center);
51                    } else if code == Key::V {
52                        cursor_visible = !cursor_visible;
53                        window.set_mouse_cursor_visible(cursor_visible);
54                    } else if code == Key::G {
55                        grabbed = !grabbed;
56                        window.set_mouse_cursor_grabbed(grabbed);
57                    }
58                }
59                _ => {}
60            }
61        }
62
63        let mp = window.mouse_position();
64        let dmp = mouse::desktop_position();
65        let cur_vis_msg = if cursor_visible {
66            "visible"
67        } else {
68            "invisible"
69        };
70        let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71        mp_text.set_string(&format!(
72            "x: {}, y: {} (Window)\n\
73             x: {}, y: {} (Desktop)\n\
74             [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75             'W' to center mouse on window\n\
76             'D' to center mouse on desktop",
77            mp.x, mp.y, dmp.x, dmp.y
78        ));
79
80        circle.set_position((mp.x as f32, mp.y as f32));
81
82        window.clear(Color::BLACK);
83        // Push texts out of each other's way
84        for i in (0..texts.len()).rev() {
85            for j in (0..i).rev() {
86                if let Some(intersect) = texts[i]
87                    .global_bounds()
88                    .intersection(&texts[j].global_bounds())
89                {
90                    texts[j].move_((0., -intersect.height));
91                }
92            }
93        }
94        texts.retain(|txt| txt.fill_color().a > 0);
95        for txt in &mut texts {
96            let mut color = txt.fill_color();
97            color.a -= 1;
98            txt.set_fill_color(color);
99            window.draw(txt);
100        }
101        if !cursor_visible {
102            window.draw(&circle);
103        }
104        window.draw(&mp_text);
105        window.display();
106    }
107    Ok(())
108}
More examples
Hide additional examples
examples/unicode-text-entry.rs (line 105)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn outline_color(&self) -> Color

Returns the outline color of the text.

Examples found in repository?
examples/unicode-text-entry.rs (line 106)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn outline_thickness(&self) -> f32

Returns the outline thickness of the text, in pixels.

Examples found in repository?
examples/unicode-text-entry.rs (line 113)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn find_character_pos(&self, index: usize) -> Vector2f

Return the position of the index-th character in a text

This function computes the visual position of a character from its index in the string. The returned position is in global coordinates (translation, rotation, scale and origin are applied). If index is out of range, the position of the end of the string is returned.

§Arguments
  • index - The index of the character

Return the position of the character

Examples found in repository?
examples/unicode-text-entry.rs (line 124)
12fn main() -> SfResult<()> {
13    example_ensure_right_working_dir();
14
15    let mut window = RenderWindow::new(
16        (800, 600),
17        "◢◤ Unicode text entry ◥◣",
18        Style::CLOSE,
19        &Default::default(),
20    )?;
21    window.set_vertical_sync_enabled(true);
22
23    // Showcase delayed initialization of font
24    let mut font = Font::new()?;
25
26    match std::env::args().nth(1) {
27        Some(path) => font.load_from_file(&path)?,
28        None => font.load_from_memory_static(include_bytes!("resources/sansation.ttf"))?,
29    };
30    let mut string = String::from("This text can be edited.\nTry it!");
31
32    let mut text = Text::new(&string, &font, 24);
33    text.set_fill_color(Color::RED);
34    text.set_outline_color(Color::YELLOW);
35    text.set_outline_thickness(2.0);
36    let mut status_text = Text::new("", &font, 16);
37    status_text.set_position((0., window.size().y as f32 - 64.0));
38    let mut bold = false;
39    let mut italic = false;
40    let mut underlined = false;
41    let mut strikethrough = false;
42    let mut show_cursor = true;
43
44    'mainloop: loop {
45        while let Some(ev) = window.poll_event() {
46            match ev {
47                Event::Closed => break 'mainloop,
48                Event::TextEntered { unicode } => {
49                    if unicode == 0x08 as char {
50                        string.pop();
51                    } else if unicode == 0xD as char {
52                        string.push('\n');
53                    }
54                    // Ignore ctrl+v/ctrl+v generated chars
55                    else if unicode != 0x16 as char && unicode != 0x03 as char {
56                        string.push(unicode);
57                    }
58                    text.set_string(&string);
59                }
60                Event::KeyPressed {
61                    code: Key::V,
62                    ctrl: true,
63                    ..
64                } => {
65                    string.push_str(&clipboard::get_string());
66                    text.set_string(&string);
67                }
68                Event::KeyPressed {
69                    code: Key::C,
70                    ctrl: true,
71                    ..
72                } => {
73                    clipboard::set_string(text.string());
74                }
75                Event::KeyPressed { code, .. } => {
76                    match code {
77                        Key::Escape => break 'mainloop,
78                        Key::F1 => bold ^= true,
79                        Key::F2 => italic ^= true,
80                        Key::F3 => underlined ^= true,
81                        Key::F4 => strikethrough ^= true,
82                        Key::F5 => show_cursor ^= true,
83                        _ => {}
84                    }
85                    let mut style = TextStyle::default();
86                    if bold {
87                        style |= TextStyle::BOLD;
88                    }
89                    if italic {
90                        style |= TextStyle::ITALIC;
91                    }
92                    if underlined {
93                        style |= TextStyle::UNDERLINED;
94                    }
95                    if strikethrough {
96                        style |= TextStyle::STRIKETHROUGH;
97                    }
98                    text.set_style(style);
99                }
100                _ => {}
101            }
102        }
103
104        let status_string = {
105            let fc = text.fill_color();
106            let oc = text.outline_color();
107            format!(
108            "fill: {:02x}{:02x}{:02x}{:02x} outline: {:02x}{:02x}{:02x}{:02x} outline thickness: {}\n\
109            style: {:?} (F1-F4) cursor: {} (F5)\n\
110            font family: {}",
111            fc.r, fc.g, fc.b, fc.a,
112            oc.r, oc.g, oc.b, oc.a,
113            text.outline_thickness(),
114            text.style(),
115            show_cursor,
116            font.info().family
117        )
118        };
119        status_text.set_string(&status_string);
120
121        window.clear(Color::BLACK);
122        window.draw(&text);
123        if show_cursor {
124            let mut end = text.find_character_pos(usize::MAX);
125            end.x += 2.0;
126            end.y += 2.0;
127            let mut rs = RectangleShape::new();
128            rs.set_fill_color(Color::TRANSPARENT);
129            rs.set_outline_color(Color::YELLOW);
130            rs.set_outline_thickness(-3.0);
131            rs.set_position(end);
132            rs.set_size((8.0, 24.0));
133            window.draw(&rs);
134        }
135        window.draw(&status_text);
136        window.display();
137    }
138    println!("The final text is {:?}", text.string().to_rust_string());
139    Ok(())
140}
Source

pub fn local_bounds(&self) -> FloatRect

Get the local bounding rectangle of a text

The returned rectangle is in local coordinates, which means that it ignores the transformations (translation, rotation, scale, …) that are applied to the entity. In other words, this function returns the bounds of the entity in the entity’s coordinate system.

Return the local bounding rectangle of the entity

Source

pub fn global_bounds(&self) -> FloatRect

Get the global bounding rectangle of a text

The returned rectangle is in global coordinates, which means that it takes in account the transformations (translation, rotation, scale, …) that are applied to the entity. In other words, this function returns the bounds of the text in the global 2D world’s coordinate system.

Return the global bounding rectangle of the entity

Examples found in repository?
examples/mouse.rs (line 87)
5fn main() -> SfResult<()> {
6    example_ensure_right_working_dir();
7
8    let mut window = RenderWindow::new(
9        (800, 600),
10        "Mouse events",
11        Style::CLOSE,
12        &Default::default(),
13    )?;
14    window.set_mouse_cursor_visible(false);
15    window.set_vertical_sync_enabled(true);
16
17    let font = Font::from_file("sansation.ttf")?;
18    let mut circle = CircleShape::new(4., 30);
19    let mut texts: Vec<Text> = Vec::new();
20    let mut mp_text = Text::new("", &font, 14);
21    let mut cursor_visible = false;
22    let mut grabbed = false;
23    macro_rules! push_text {
24        ($x:expr, $y:expr, $fmt:expr, $($arg:tt)*) => {
25            let mut text = Text::new(&format!($fmt, $($arg)*), &font, 14);
26            text.set_position(($x as f32, $y as f32));
27            texts.push(text);
28        }
29    }
30
31    'mainloop: loop {
32        while let Some(ev) = window.poll_event() {
33            match ev {
34                Event::Closed => break 'mainloop,
35                Event::MouseWheelScrolled { wheel, delta, x, y } => {
36                    push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y);
37                }
38                Event::MouseButtonPressed { button, x, y } => {
39                    push_text!(x, y, "Press: {:?}, {}, {}", button, x, y);
40                }
41                Event::MouseButtonReleased { button, x, y } => {
42                    push_text!(x, y, "Release: {:?}, {}, {}", button, x, y);
43                }
44                Event::KeyPressed { code, .. } => {
45                    if code == Key::W {
46                        window.set_mouse_position(Vector2i::new(400, 300));
47                    } else if code == Key::D {
48                        let dm = VideoMode::desktop_mode();
49                        let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2);
50                        mouse::set_desktop_position(center);
51                    } else if code == Key::V {
52                        cursor_visible = !cursor_visible;
53                        window.set_mouse_cursor_visible(cursor_visible);
54                    } else if code == Key::G {
55                        grabbed = !grabbed;
56                        window.set_mouse_cursor_grabbed(grabbed);
57                    }
58                }
59                _ => {}
60            }
61        }
62
63        let mp = window.mouse_position();
64        let dmp = mouse::desktop_position();
65        let cur_vis_msg = if cursor_visible {
66            "visible"
67        } else {
68            "invisible"
69        };
70        let grab_msg = if grabbed { "grabbed" } else { "not grabbed" };
71        mp_text.set_string(&format!(
72            "x: {}, y: {} (Window)\n\
73             x: {}, y: {} (Desktop)\n\
74             [{cur_vis_msg}] [{grab_msg}] ('V'/'G') to toggle\n\
75             'W' to center mouse on window\n\
76             'D' to center mouse on desktop",
77            mp.x, mp.y, dmp.x, dmp.y
78        ));
79
80        circle.set_position((mp.x as f32, mp.y as f32));
81
82        window.clear(Color::BLACK);
83        // Push texts out of each other's way
84        for i in (0..texts.len()).rev() {
85            for j in (0..i).rev() {
86                if let Some(intersect) = texts[i]
87                    .global_bounds()
88                    .intersection(&texts[j].global_bounds())
89                {
90                    texts[j].move_((0., -intersect.height));
91                }
92            }
93        }
94        texts.retain(|txt| txt.fill_color().a > 0);
95        for txt in &mut texts {
96            let mut color = txt.fill_color();
97            color.a -= 1;
98            txt.set_fill_color(color);
99            window.draw(txt);
100        }
101        if !cursor_visible {
102            window.draw(&circle);
103        }
104        window.draw(&mp_text);
105        window.display();
106    }
107    Ok(())
108}
Source

pub fn line_spacing(&self) -> f32

Get the size of the line spacing factor.

Source

pub fn set_line_spacing(&mut self, factor: f32)

Set the line spacing factor.

The default spacing between lines is defined by the font. This method enables you to set a factor for the spacing between lines. By default the line spacing factor is 1.

Source

pub fn letter_spacing(&self) -> f32

Get the size of the letter spacing factor.

Source

pub fn set_letter_spacing(&mut self, factor: f32)

Set the letter spacing factor.

The default spacing between letters is defined by the font. This factor doesn’t directly apply to the existing spacing between each character, it rather adds a fixed space between them which is calculated from the font metrics and the character size. Note that factors below 1 (including negative numbers) bring characters closer to each other. By default the letter spacing factor is 1.

Trait Implementations§

Source§

impl<'s> Clone for Text<'s>

Source§

fn clone(&self) -> Text<'s>

Return a new Text or panic! if there is not enough memory

1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'s> Debug for Text<'s>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Text<'_>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Drawable for Text<'_>

Source§

fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>( &'a self, target: &mut dyn RenderTarget, states: &RenderStates<'texture, 'shader, 'shader_texture>, )

Draws into target with RenderStates states.
Source§

impl Drop for Text<'_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Transformable for Text<'_>

Source§

fn set_position<P: Into<Vector2f>>(&mut self, position: P)

Sets the position of the object. Read more
Source§

fn set_rotation(&mut self, angle: f32)

Set the orientation of the object in degrees. Read more
Source§

fn set_scale<S: Into<Vector2f>>(&mut self, scale: S)

Sets the scale factors of the object. Read more
Source§

fn set_origin<O: Into<Vector2f>>(&mut self, origin: O)

Sets the local origin of the object. Read more
Source§

fn position(&self) -> Vector2f

Gets the position of the object.
Source§

fn rotation(&self) -> f32

Gets the rotation of the object in degrees. Read more
Source§

fn get_scale(&self) -> Vector2f

Gets the current scale of the object.
Source§

fn origin(&self) -> Vector2f

Gets the local origin of the object.
Source§

fn move_<O: Into<Vector2f>>(&mut self, offset: O)

Moves the object by a given offset. Read more
Source§

fn rotate(&mut self, angle: f32)

Rotates the object. Read more
Source§

fn scale<F: Into<Vector2f>>(&mut self, factors: F)

Scales the object. Read more
Source§

fn transform(&self) -> &Transform

Gets the combined transform of the object.
Source§

fn inverse_transform(&self) -> &Transform

Gets the inverse combined transform of the object.

Auto Trait Implementations§

§

impl<'s> Freeze for Text<'s>

§

impl<'s> RefUnwindSafe for Text<'s>

§

impl<'s> !Send for Text<'s>

§

impl<'s> !Sync for Text<'s>

§

impl<'s> Unpin for Text<'s>

§

impl<'s> UnwindSafe for Text<'s>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.