Text

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?
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}
121
122struct StormBlink {
123    points: Vec<Vertex>,
124    shader: FBox<Shader<'static>>,
125}
126
127impl StormBlink {
128    fn new() -> SfResult<Self> {
129        let mut rng = SmallRng::seed_from_u64(1);
130
131        let mut points = Vec::new();
132        for _ in 0..40_000 {
133            let x = rng.random_range(0.0..800.);
134            let y = rng.random_range(0.0..600.);
135            let (red, green, blue) = (rng.random(), rng.random(), rng.random());
136            points.push(Vertex::with_pos_color(
137                Vector2f::new(x, y),
138                Color::rgb(red, green, blue),
139            ));
140        }
141
142        let shader = Shader::from_file_vert_frag("storm.vert", "blink.frag")?;
143        Ok(Self { points, shader })
144    }
145}
146
147impl Drawable for StormBlink {
148    fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
149        &'a self,
150        target: &mut dyn RenderTarget,
151        states: &RenderStates<'texture, 'shader, 'shader_texture>,
152    ) {
153        let mut states = *states;
154        states.shader = Some(&self.shader);
155        target.draw_primitives(&self.points, PrimitiveType::POINTS, &states);
156    }
157}
158
159impl Effect for StormBlink {
160    fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
161        let radius = 200. + t.cos() * 150.;
162        self.shader
163            .set_uniform_vec2("storm_position", Vector2f::new(x * 800., y * 600.))?;
164        self.shader
165            .set_uniform_float("storm_inner_radius", radius / 3.)?;
166        self.shader
167            .set_uniform_float("storm_total_radius", radius)?;
168        self.shader
169            .set_uniform_float("blink_alpha", 0.5 + (t * 3.).cos() * 0.25)
170    }
171    fn name(&self) -> &str {
172        "storm + blink"
173    }
174}
175
176struct Edge<'t> {
177    surface: FBox<RenderTexture>,
178    bg_sprite: Sprite<'t>,
179    entities: Vec<Sprite<'t>>,
180    shader: FBox<Shader<'static>>,
181}
182
183impl<'t> Edge<'t> {
184    fn new(bg_texture: &'t Texture, entity_texture: &'t Texture) -> SfResult<Self> {
185        let mut surface = RenderTexture::new(800, 600)?;
186        surface.set_smooth(true);
187        let mut bg_sprite = Sprite::with_texture(bg_texture);
188        bg_sprite.set_position((135., 100.));
189        let mut entities = Vec::new();
190
191        for i in 0..6 {
192            entities.push(Sprite::with_texture_and_rect(
193                entity_texture,
194                IntRect::new(96 * i, 0, 96, 96),
195            ));
196        }
197
198        let mut shader = Shader::from_file("edge.frag", ShaderType::Fragment)?;
199        shader.set_uniform_current_texture("texture")?;
200
201        Ok(Self {
202            surface,
203            bg_sprite,
204            entities,
205            shader,
206        })
207    }
208}
209
210impl Drawable for Edge<'_> {
211    fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
212        &'a self,
213        target: &mut dyn RenderTarget,
214        states: &RenderStates<'texture, 'shader, 'shader_texture>,
215    ) {
216        let mut states = *states;
217        states.shader = Some(&self.shader);
218        target.draw_with_renderstates(&Sprite::with_texture(self.surface.texture()), &states);
219    }
220}
221
222impl Effect for Edge<'_> {
223    fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
224        self.shader
225            .set_uniform_float("edge_threshold", 1. - (x + y) / 2.)?;
226        let entities_len = self.entities.len() as f32;
227
228        for (i, en) in self.entities.iter_mut().enumerate() {
229            let pos = (
230                (0.25 * (t * i as f32 + (entities_len - i as f32))).cos() * 300. + 350.,
231                (0.25 * (t * (entities_len - i as f32) + i as f32)).cos() * 200. + 250.,
232            );
233            en.set_position(pos);
234        }
235        self.surface.clear(Color::WHITE);
236        self.surface.draw(&self.bg_sprite);
237        for en in &self.entities {
238            self.surface.draw(en);
239        }
240        self.surface.display();
241        Ok(())
242    }
243    fn name(&self) -> &str {
244        "edge post-effect"
245    }
246}
247
248struct Geometry<'tex> {
249    point_cloud: [Vertex; 10_000],
250    shader: FBox<Shader<'tex>>,
251    texture: &'tex Texture,
252    transform: Transform,
253}
254
255impl<'tex> Geometry<'tex> {
256    fn new(texture: &'tex Texture) -> SfResult<Self> {
257        if !Shader::is_geometry_available() {
258            eprintln!("Geometry shaders not available");
259            return Err(SfError::CallFailed);
260        }
261        let mut shader = Shader::from_memory_all(
262            include_str!("resources/billboard.vert"),
263            include_str!("resources/billboard.geom"),
264            include_str!("resources/billboard.frag"),
265        )?;
266        shader.set_uniform_texture("texture", texture)?;
267        shader.set_uniform_vec2("resolution", (800., 600.).into())?;
268        let mut rng = SmallRng::seed_from_u64(1);
269        Ok(Self {
270            point_cloud: std::array::from_fn(|_| {
271                Vertex::new(
272                    (
273                        rng.random_range(-480.0..480.0),
274                        rng.random_range(-480.0..480.0),
275                    )
276                        .into(),
277                    Color::WHITE,
278                    Default::default(),
279                )
280            }),
281            shader,
282            texture,
283            transform: Transform::IDENTITY,
284        })
285    }
286}
287
288impl Drawable for Geometry<'_> {
289    fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
290        &'a self,
291        target: &mut dyn RenderTarget,
292        states: &RenderStates<'texture, 'shader, 'shader_texture>,
293    ) {
294        let mut states = *states;
295        states.shader = Some(&self.shader);
296        states.texture = Some(self.texture);
297        states.transform = self.transform;
298        target.draw_primitives(&self.point_cloud, PrimitiveType::POINTS, &states);
299    }
300}
301
302impl Effect for Geometry<'_> {
303    fn update(&mut self, _t: f32, x: f32, y: f32) -> SfResult<()> {
304        self.transform = Transform::IDENTITY;
305        self.transform.translate(400., 300.);
306        self.transform.rotate(x * 360.0);
307        let size = 25. + y.abs() * 50.;
308        self.shader.set_uniform_vec2("size", size.into())?;
309        Ok(())
310    }
311
312    fn name(&self) -> &str {
313        "Geometry Shader Billboards"
314    }
315}
316
317fn main() -> SfResult<()> {
318    example_ensure_right_working_dir();
319
320    let mut window = RenderWindow::new(
321        (800, 600),
322        "SFML Shader",
323        Style::TITLEBAR | Style::CLOSE,
324        &Default::default(),
325    )?;
326    window.set_vertical_sync_enabled(true);
327    let font = Font::from_file("sansation.ttf")?;
328    let bg = Texture::from_file("background.jpg")?;
329    let mut bg_texture = Texture::from_file("sfml.png")?;
330    bg_texture.set_smooth(true);
331    let mut entity_texture = Texture::from_file("devices.png")?;
332    entity_texture.set_smooth(true);
333    let logo_texture = Texture::from_file("logo.png")?;
334    let effects: [&mut dyn Effect; 5] = [
335        &mut Pixelate::new(&bg)?,
336        &mut WaveBlur::new(&font)?,
337        &mut StormBlink::new()?,
338        &mut Edge::new(&bg_texture, &entity_texture)?,
339        &mut Geometry::new(&logo_texture)?,
340    ];
341    let mut current = 0;
342    let text_bg_texture = Texture::from_file("text-background.png")?;
343    let mut text_bg = Sprite::with_texture(&text_bg_texture);
344    text_bg.set_position((0., 520.));
345    text_bg.set_color(Color::rgba(255, 255, 255, 200));
346    let msg = format!("Current effect: {}", effects[current].name());
347    let mut desc = Text::new(&msg, &font, 20);
348    desc.set_position((10., 530.));
349    desc.set_fill_color(Color::rgb(80, 80, 80));
350    let msg = "Press left and right arrows to change the current shader";
351    let mut instructions = Text::new(msg, &font, 20);
352    instructions.set_position((280., 555.));
353    instructions.set_fill_color(Color::rgb(80, 80, 80));
354    let clock = Clock::start()?;
355
356    while window.is_open() {
357        while let Some(event) = window.poll_event() {
358            use crate::Event::*;
359            match event {
360                Closed => window.close(),
361                KeyPressed { code, .. } => match code {
362                    Key::Escape => window.close(),
363                    Key::Left => {
364                        if current == 0 {
365                            current = effects.len() - 1;
366                        } else {
367                            current -= 1;
368                        }
369                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
370                    }
371                    Key::Right => {
372                        if current == effects.len() - 1 {
373                            current = 0;
374                        } else {
375                            current += 1;
376                        }
377                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
378                    }
379                    _ => {}
380                },
381                _ => {}
382            }
383        }
384
385        let x = window.mouse_position().x as f32 / window.size().x as f32;
386        let y = window.mouse_position().y as f32 / window.size().y as f32;
387
388        effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
389
390        window.clear(Color::rgb(255, 128, 0));
391        window.draw(effects[current]);
392        window.draw(&text_bg);
393        window.draw(&instructions);
394        window.draw(&desc);
395        window.display();
396    }
397    Ok(())
398}
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)
More examples
Hide additional examples
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 369)
317fn main() -> SfResult<()> {
318    example_ensure_right_working_dir();
319
320    let mut window = RenderWindow::new(
321        (800, 600),
322        "SFML Shader",
323        Style::TITLEBAR | Style::CLOSE,
324        &Default::default(),
325    )?;
326    window.set_vertical_sync_enabled(true);
327    let font = Font::from_file("sansation.ttf")?;
328    let bg = Texture::from_file("background.jpg")?;
329    let mut bg_texture = Texture::from_file("sfml.png")?;
330    bg_texture.set_smooth(true);
331    let mut entity_texture = Texture::from_file("devices.png")?;
332    entity_texture.set_smooth(true);
333    let logo_texture = Texture::from_file("logo.png")?;
334    let effects: [&mut dyn Effect; 5] = [
335        &mut Pixelate::new(&bg)?,
336        &mut WaveBlur::new(&font)?,
337        &mut StormBlink::new()?,
338        &mut Edge::new(&bg_texture, &entity_texture)?,
339        &mut Geometry::new(&logo_texture)?,
340    ];
341    let mut current = 0;
342    let text_bg_texture = Texture::from_file("text-background.png")?;
343    let mut text_bg = Sprite::with_texture(&text_bg_texture);
344    text_bg.set_position((0., 520.));
345    text_bg.set_color(Color::rgba(255, 255, 255, 200));
346    let msg = format!("Current effect: {}", effects[current].name());
347    let mut desc = Text::new(&msg, &font, 20);
348    desc.set_position((10., 530.));
349    desc.set_fill_color(Color::rgb(80, 80, 80));
350    let msg = "Press left and right arrows to change the current shader";
351    let mut instructions = Text::new(msg, &font, 20);
352    instructions.set_position((280., 555.));
353    instructions.set_fill_color(Color::rgb(80, 80, 80));
354    let clock = Clock::start()?;
355
356    while window.is_open() {
357        while let Some(event) = window.poll_event() {
358            use crate::Event::*;
359            match event {
360                Closed => window.close(),
361                KeyPressed { code, .. } => match code {
362                    Key::Escape => window.close(),
363                    Key::Left => {
364                        if current == 0 {
365                            current = effects.len() - 1;
366                        } else {
367                            current -= 1;
368                        }
369                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
370                    }
371                    Key::Right => {
372                        if current == effects.len() - 1 {
373                            current = 0;
374                        } else {
375                            current += 1;
376                        }
377                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
378                    }
379                    _ => {}
380                },
381                _ => {}
382            }
383        }
384
385        let x = window.mouse_position().x as f32 / window.size().x as f32;
386        let y = window.mouse_position().y as f32 / window.size().y as f32;
387
388        effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
389
390        window.clear(Color::rgb(255, 128, 0));
391        window.draw(effects[current]);
392        window.draw(&text_bg);
393        window.draw(&instructions);
394        window.draw(&desc);
395        window.display();
396    }
397    Ok(())
398}
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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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 = SmallRng::seed_from_u64(1);
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.random_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.random_range(0.0..20.) * PI / 180.;
234                } else {
235                    ball_angle = PI - ball_angle - rng.random_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.random_range(0.0..20.) * PI / 180.;
253                } else {
254                    ball_angle = PI - ball_angle - rng.random_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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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 = SmallRng::seed_from_u64(1);
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.random_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.random_range(0.0..20.) * PI / 180.;
234                } else {
235                    ball_angle = PI - ball_angle - rng.random_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.random_range(0.0..20.) * PI / 180.;
253                } else {
254                    ball_angle = PI - ball_angle - rng.random_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 120)
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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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?
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 349)
317fn main() -> SfResult<()> {
318    example_ensure_right_working_dir();
319
320    let mut window = RenderWindow::new(
321        (800, 600),
322        "SFML Shader",
323        Style::TITLEBAR | Style::CLOSE,
324        &Default::default(),
325    )?;
326    window.set_vertical_sync_enabled(true);
327    let font = Font::from_file("sansation.ttf")?;
328    let bg = Texture::from_file("background.jpg")?;
329    let mut bg_texture = Texture::from_file("sfml.png")?;
330    bg_texture.set_smooth(true);
331    let mut entity_texture = Texture::from_file("devices.png")?;
332    entity_texture.set_smooth(true);
333    let logo_texture = Texture::from_file("logo.png")?;
334    let effects: [&mut dyn Effect; 5] = [
335        &mut Pixelate::new(&bg)?,
336        &mut WaveBlur::new(&font)?,
337        &mut StormBlink::new()?,
338        &mut Edge::new(&bg_texture, &entity_texture)?,
339        &mut Geometry::new(&logo_texture)?,
340    ];
341    let mut current = 0;
342    let text_bg_texture = Texture::from_file("text-background.png")?;
343    let mut text_bg = Sprite::with_texture(&text_bg_texture);
344    text_bg.set_position((0., 520.));
345    text_bg.set_color(Color::rgba(255, 255, 255, 200));
346    let msg = format!("Current effect: {}", effects[current].name());
347    let mut desc = Text::new(&msg, &font, 20);
348    desc.set_position((10., 530.));
349    desc.set_fill_color(Color::rgb(80, 80, 80));
350    let msg = "Press left and right arrows to change the current shader";
351    let mut instructions = Text::new(msg, &font, 20);
352    instructions.set_position((280., 555.));
353    instructions.set_fill_color(Color::rgb(80, 80, 80));
354    let clock = Clock::start()?;
355
356    while window.is_open() {
357        while let Some(event) = window.poll_event() {
358            use crate::Event::*;
359            match event {
360                Closed => window.close(),
361                KeyPressed { code, .. } => match code {
362                    Key::Escape => window.close(),
363                    Key::Left => {
364                        if current == 0 {
365                            current = effects.len() - 1;
366                        } else {
367                            current -= 1;
368                        }
369                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
370                    }
371                    Key::Right => {
372                        if current == effects.len() - 1 {
373                            current = 0;
374                        } else {
375                            current += 1;
376                        }
377                        desc.set_string(&format!("Current effect: {}", effects[current].name()));
378                    }
379                    _ => {}
380                },
381                _ => {}
382            }
383        }
384
385        let x = window.mouse_position().x as f32 / window.size().x as f32;
386        let y = window.mouse_position().y as f32 / window.size().y as f32;
387
388        effects[current].update(clock.elapsed_time().as_seconds(), x, y)?;
389
390        window.clear(Color::rgb(255, 128, 0));
391        window.draw(effects[current]);
392        window.draw(&text_bg);
393        window.draw(&instructions);
394        window.draw(&desc);
395        window.display();
396    }
397    Ok(())
398}
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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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 = SmallRng::seed_from_u64(1);
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.random_range(-3.0..3.0), 0.0),
124                    image_id: click_counter % N_IMAGES,
125                    angle: 0.0,
126                    rot_speed: rng.random_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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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 = SmallRng::seed_from_u64(1);
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.random_range(-3.0..3.0), 0.0),
124                    image_id: click_counter % N_IMAGES,
125                    angle: 0.0,
126                    rot_speed: rng.random_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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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 119)
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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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 130)
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,
112                fc.g,
113                fc.b,
114                fc.a,
115                oc.r,
116                oc.g,
117                oc.b,
118                oc.a,
119                text.outline_thickness(),
120                text.style(),
121                show_cursor,
122                font.info().family
123            )
124        };
125        status_text.set_string(&status_string);
126
127        window.clear(Color::BLACK);
128        window.draw(&text);
129        if show_cursor {
130            let mut end = text.find_character_pos(usize::MAX);
131            end.x += 2.0;
132            end.y += 2.0;
133            let mut rs = RectangleShape::new();
134            rs.set_fill_color(Color::TRANSPARENT);
135            rs.set_outline_color(Color::YELLOW);
136            rs.set_outline_thickness(-3.0);
137            rs.set_position(end);
138            rs.set_size((8.0, 24.0));
139            window.draw(&rs);
140        }
141        window.draw(&status_text);
142        window.display();
143    }
144    println!("The final text is {:?}", text.string().to_rust_string());
145    Ok(())
146}
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.