Skip to main content

ParagraphBuilder

Struct ParagraphBuilder 

Source
pub struct ParagraphBuilder(/* private fields */);
Expand description

Paragraph builders allow for the creation of fully laid out paragraphs (which themselves are immutable).

This is not thread-safe, as TypoGraphy context is not thread-safe. But Paragraph is thread-safe.

https://api.flutter.dev/flutter/dart-ui/ParagraphBuilder-class.html

To build a paragraph, users push/pop paragraph styles onto a stack then add UTF-8 encoded text. The properties on the top of paragraph style stack when the text is added are used to layout and shape that subset of the paragraph.

@see ParagraphStyle

// this contains the fonts from user's system (or you can add custom fonts)
let fonts = TypographyContext::default();
// style decides the appearance of the text
let mut style = ParagraphStyle::default();
style.set_font_family("Arial");
style.set_font_size(12.0);
let mut builder = ParagraphBuilder::new(&fonts).expect("failed to create para builder");
builder.push_style(&style); // DON'T forget to set the style before adding text
builder.add_text("Hello, world!\n");
style.set_font_size(24.0);
builder.push_style(&style);
builder.add_text("Big World!\n"); // 24.0 font size
builder.pop_style(); // the 24.0 style is popped off. the previous 12.0 style is used
builder.add_text("Small World!\n"); // 12.0 font size
let paragraph = builder.build(100.0).expect("building paragraph failed");

Implementations§

Source§

impl ParagraphBuilder

Source

pub fn new(context: &TypographyContext) -> Option<ParagraphBuilder>

Create a new paragraph builder.

@return The paragraph builder.

Examples found in repository?
examples/basic_text.rs (line 13)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let dl = {
9        let mut builder = DisplayListBuilder::new(None);
10        let mut paint = Paint::default();
11        let paragraph = {
12            let ttx = TypographyContext::default(); // register any custom fonts if you want
13            let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
14            let mut pstyle = ParagraphStyle::default();
15            // you can set a custom font family if you want, but lets just use the system fonts
16            pstyle.set_font_size(48.0);
17            pstyle.set_font_weight(FontWeight::ExtraBold);
18            paint.set_color(Color::BLUEBERRY);
19            pstyle.set_foreground(&paint);
20            puilder.push_style(&pstyle);
21            puilder.add_text("HELLO EVERYONE");
22            puilder.build(600.0).unwrap()
23        };
24
25        paint.set_color(Color::BLACK); // clear with black first
26        builder.draw_paint(&paint);
27        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
28        builder.build().unwrap()
29    };
30    framework.enter_event_loop(Some(dl), None);
31}
More examples
Hide additional examples
examples/complex_text.rs (line 13)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let dl = {
9        let mut builder = DisplayListBuilder::new(None);
10        let mut paint = Paint::default();
11        let paragraph = {
12            let ttx = TypographyContext::default(); // register any custom fonts if you want
13            let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
14            let mut pstyle = ParagraphStyle::default();
15            // you can set a custom font family if you want, but lets just use the system fonts
16            pstyle.set_font_size(48.0);
17            pstyle.set_font_weight(FontWeight::ExtraBold);
18            paint.set_color(Color::BLUEBERRY);
19            pstyle.set_foreground(&paint);
20            puilder.push_style(&pstyle);
21            puilder.add_text("HELLO EVERYONE");
22            puilder.build(600.0).unwrap()
23        };
24
25        paint.set_color(Color::BLACK); // clear with black first
26        builder.draw_paint(&paint);
27        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
28        builder.build().unwrap()
29    };
30    framework.enter_event_loop(Some(dl), None);
31}
examples/line_metrics.rs (line 11)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let mut paint = Paint::default(); // paint object to reuse
9    let paragraph = {
10        let ttx = TypographyContext::default(); // register any custom fonts if you want
11        let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
12        let mut pstyle = ParagraphStyle::default();
13        // you can set a custom font family if you want, but lets just use the system fonts
14        pstyle.set_font_size(48.0);
15        pstyle.set_font_weight(FontWeight::ExtraBold);
16        paint.set_color(Color::BLUEBERRY);
17        pstyle.set_foreground(&paint);
18        puilder.push_style(&pstyle);
19        puilder.add_text("HELLO EVERYONE");
20        puilder.build(600.0).unwrap()
21    };
22    let metrics = paragraph.get_line_metrics().unwrap();
23    dbg!(metrics.get_width(0));
24    dbg!(metrics.get_height(0));
25    dbg!(metrics.get_ascent(0));
26    dbg!(metrics.get_descent(0));
27    dbg!(metrics.get_baseline(0));
28    dbg!(metrics.get_left(0));
29    dbg!(metrics.get_unscaled_ascent(0));
30    dbg!(metrics.get_code_unit_start_index_utf16(0));
31
32    let dl = {
33        let mut builder = DisplayListBuilder::new(None);
34        paint.set_color(Color::BLACK); // clear with black first
35        builder.draw_paint(&paint);
36        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
37        builder.build().unwrap()
38    };
39    framework.enter_event_loop(Some(dl), None);
40}
examples/common.rs (line 148)
75    pub fn enter_event_loop(
76        mut self,
77        dl: Option<DisplayList>,
78        mut user_callback: Option<UserCallback>,
79    ) {
80        let mut previous_instant = std::time::Instant::now();
81        let mut current_frame = 0;
82        let mut fps = 0;
83        let mut vsync = true;
84        // enter event loop
85        while !self.window.should_close() {
86            {
87                // record fps
88                if previous_instant.elapsed().as_secs_f64() >= 1.0 {
89                    fps = current_frame;
90                    current_frame = 0;
91                    previous_instant = std::time::Instant::now();
92                }
93                current_frame += 1;
94            }
95            self.events.clear();
96            // check events
97            self.gtx.poll_events();
98            for (_, event) in flush_messages(&self.receiver) {
99                match &event {
100                    WindowEvent::Close => {
101                        self.window.set_should_close(true);
102                    }
103                    WindowEvent::FramebufferSize(w, h) => {
104                        unsafe {
105                            self.glow_ctx.viewport(0, 0, *w, *h);
106                        }
107                        println!("window resized to {}x{}", w, h);
108                    }
109                    WindowEvent::Key(Key::Space, _, Action::Release, _) => {
110                        vsync = !vsync;
111                        println!("setting vsync to {vsync}");
112
113                        self.gtx.set_swap_interval(if vsync {
114                            SwapInterval::Sync(1)
115                        } else {
116                            SwapInterval::None
117                        });
118                    }
119                    _ => {}
120                }
121                self.events.push(event);
122            }
123
124            let (width, height) = self.window.get_framebuffer_size();
125            // init surface by wrapping default framebuffer (fbo = 0)
126            let mut surface = unsafe {
127                self.itx.wrap_fbo(
128                    0,
129                    PixelFormat::RGBA8888,
130                    ISize::new(width.into(), height.into()),
131                )
132            }
133            .expect("failed to wrap window's framebuffer");
134            let mut dl_builder = DisplayListBuilder::new(Some(&Rect::from_size(
135                [width as f32, height as f32].into(),
136            )));
137
138            if let Some(dl) = dl.as_ref() {
139                dl_builder.draw_display_list(dl, 1.0);
140            }
141            // call user callback
142            if let Some(cb) = user_callback.as_mut() {
143                if let Some(display_list) = cb(&mut self) {
144                    dl_builder.draw_display_list(&display_list, 1.0);
145                }
146            }
147            {
148                let mut para_builder = ParagraphBuilder::new(&self.ttx).unwrap();
149                para_builder.push_style(&self.style);
150                para_builder.add_text(&format!("avg fps: {fps}"));
151                let para = para_builder.build(1000.0).unwrap();
152                dl_builder.draw_paragraph(&para, Point::origin());
153            }
154            surface
155                .draw_display_list(&dl_builder.build().unwrap())
156                .unwrap();
157
158            // submit frame and wait for vsync
159            self.window.swap_buffers();
160        }
161    }
Source

pub fn push_style(&mut self, style: &ParagraphStyle) -> &mut Self

Push a new paragraph style onto the paragraph style stack managed by the paragraph builder.

Not all paragraph styles can be combined. For instance, it does not make sense to mix text alignment for different text runs within a paragraph. In such cases, the preference of the the first paragraph style on the style stack will take hold.

If text is pushed onto the paragraph builder without a style previously pushed onto the stack, a default paragraph text style will be used. This may not always be desirable because some style element cannot be overridden. It is recommended that a default paragraph style always be pushed onto the stack before the addition of any text.

  • style The style.
Examples found in repository?
examples/basic_text.rs (line 20)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let dl = {
9        let mut builder = DisplayListBuilder::new(None);
10        let mut paint = Paint::default();
11        let paragraph = {
12            let ttx = TypographyContext::default(); // register any custom fonts if you want
13            let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
14            let mut pstyle = ParagraphStyle::default();
15            // you can set a custom font family if you want, but lets just use the system fonts
16            pstyle.set_font_size(48.0);
17            pstyle.set_font_weight(FontWeight::ExtraBold);
18            paint.set_color(Color::BLUEBERRY);
19            pstyle.set_foreground(&paint);
20            puilder.push_style(&pstyle);
21            puilder.add_text("HELLO EVERYONE");
22            puilder.build(600.0).unwrap()
23        };
24
25        paint.set_color(Color::BLACK); // clear with black first
26        builder.draw_paint(&paint);
27        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
28        builder.build().unwrap()
29    };
30    framework.enter_event_loop(Some(dl), None);
31}
More examples
Hide additional examples
examples/complex_text.rs (line 20)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let dl = {
9        let mut builder = DisplayListBuilder::new(None);
10        let mut paint = Paint::default();
11        let paragraph = {
12            let ttx = TypographyContext::default(); // register any custom fonts if you want
13            let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
14            let mut pstyle = ParagraphStyle::default();
15            // you can set a custom font family if you want, but lets just use the system fonts
16            pstyle.set_font_size(48.0);
17            pstyle.set_font_weight(FontWeight::ExtraBold);
18            paint.set_color(Color::BLUEBERRY);
19            pstyle.set_foreground(&paint);
20            puilder.push_style(&pstyle);
21            puilder.add_text("HELLO EVERYONE");
22            puilder.build(600.0).unwrap()
23        };
24
25        paint.set_color(Color::BLACK); // clear with black first
26        builder.draw_paint(&paint);
27        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
28        builder.build().unwrap()
29    };
30    framework.enter_event_loop(Some(dl), None);
31}
examples/line_metrics.rs (line 18)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let mut paint = Paint::default(); // paint object to reuse
9    let paragraph = {
10        let ttx = TypographyContext::default(); // register any custom fonts if you want
11        let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
12        let mut pstyle = ParagraphStyle::default();
13        // you can set a custom font family if you want, but lets just use the system fonts
14        pstyle.set_font_size(48.0);
15        pstyle.set_font_weight(FontWeight::ExtraBold);
16        paint.set_color(Color::BLUEBERRY);
17        pstyle.set_foreground(&paint);
18        puilder.push_style(&pstyle);
19        puilder.add_text("HELLO EVERYONE");
20        puilder.build(600.0).unwrap()
21    };
22    let metrics = paragraph.get_line_metrics().unwrap();
23    dbg!(metrics.get_width(0));
24    dbg!(metrics.get_height(0));
25    dbg!(metrics.get_ascent(0));
26    dbg!(metrics.get_descent(0));
27    dbg!(metrics.get_baseline(0));
28    dbg!(metrics.get_left(0));
29    dbg!(metrics.get_unscaled_ascent(0));
30    dbg!(metrics.get_code_unit_start_index_utf16(0));
31
32    let dl = {
33        let mut builder = DisplayListBuilder::new(None);
34        paint.set_color(Color::BLACK); // clear with black first
35        builder.draw_paint(&paint);
36        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
37        builder.build().unwrap()
38    };
39    framework.enter_event_loop(Some(dl), None);
40}
examples/common.rs (line 149)
75    pub fn enter_event_loop(
76        mut self,
77        dl: Option<DisplayList>,
78        mut user_callback: Option<UserCallback>,
79    ) {
80        let mut previous_instant = std::time::Instant::now();
81        let mut current_frame = 0;
82        let mut fps = 0;
83        let mut vsync = true;
84        // enter event loop
85        while !self.window.should_close() {
86            {
87                // record fps
88                if previous_instant.elapsed().as_secs_f64() >= 1.0 {
89                    fps = current_frame;
90                    current_frame = 0;
91                    previous_instant = std::time::Instant::now();
92                }
93                current_frame += 1;
94            }
95            self.events.clear();
96            // check events
97            self.gtx.poll_events();
98            for (_, event) in flush_messages(&self.receiver) {
99                match &event {
100                    WindowEvent::Close => {
101                        self.window.set_should_close(true);
102                    }
103                    WindowEvent::FramebufferSize(w, h) => {
104                        unsafe {
105                            self.glow_ctx.viewport(0, 0, *w, *h);
106                        }
107                        println!("window resized to {}x{}", w, h);
108                    }
109                    WindowEvent::Key(Key::Space, _, Action::Release, _) => {
110                        vsync = !vsync;
111                        println!("setting vsync to {vsync}");
112
113                        self.gtx.set_swap_interval(if vsync {
114                            SwapInterval::Sync(1)
115                        } else {
116                            SwapInterval::None
117                        });
118                    }
119                    _ => {}
120                }
121                self.events.push(event);
122            }
123
124            let (width, height) = self.window.get_framebuffer_size();
125            // init surface by wrapping default framebuffer (fbo = 0)
126            let mut surface = unsafe {
127                self.itx.wrap_fbo(
128                    0,
129                    PixelFormat::RGBA8888,
130                    ISize::new(width.into(), height.into()),
131                )
132            }
133            .expect("failed to wrap window's framebuffer");
134            let mut dl_builder = DisplayListBuilder::new(Some(&Rect::from_size(
135                [width as f32, height as f32].into(),
136            )));
137
138            if let Some(dl) = dl.as_ref() {
139                dl_builder.draw_display_list(dl, 1.0);
140            }
141            // call user callback
142            if let Some(cb) = user_callback.as_mut() {
143                if let Some(display_list) = cb(&mut self) {
144                    dl_builder.draw_display_list(&display_list, 1.0);
145                }
146            }
147            {
148                let mut para_builder = ParagraphBuilder::new(&self.ttx).unwrap();
149                para_builder.push_style(&self.style);
150                para_builder.add_text(&format!("avg fps: {fps}"));
151                let para = para_builder.build(1000.0).unwrap();
152                dl_builder.draw_paragraph(&para, Point::origin());
153            }
154            surface
155                .draw_display_list(&dl_builder.build().unwrap())
156                .unwrap();
157
158            // submit frame and wait for vsync
159            self.window.swap_buffers();
160        }
161    }
Source

pub fn pop_style(&mut self) -> &mut Self

Pop a previously pushed paragraph style from the paragraph style stack.

Source

pub fn add_text(&mut self, text: &str) -> &mut Self

Add UTF-8 encoded text to the paragraph. The text will be styled according to the paragraph style already on top of the paragraph style stack.

Examples found in repository?
examples/basic_text.rs (line 21)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let dl = {
9        let mut builder = DisplayListBuilder::new(None);
10        let mut paint = Paint::default();
11        let paragraph = {
12            let ttx = TypographyContext::default(); // register any custom fonts if you want
13            let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
14            let mut pstyle = ParagraphStyle::default();
15            // you can set a custom font family if you want, but lets just use the system fonts
16            pstyle.set_font_size(48.0);
17            pstyle.set_font_weight(FontWeight::ExtraBold);
18            paint.set_color(Color::BLUEBERRY);
19            pstyle.set_foreground(&paint);
20            puilder.push_style(&pstyle);
21            puilder.add_text("HELLO EVERYONE");
22            puilder.build(600.0).unwrap()
23        };
24
25        paint.set_color(Color::BLACK); // clear with black first
26        builder.draw_paint(&paint);
27        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
28        builder.build().unwrap()
29    };
30    framework.enter_event_loop(Some(dl), None);
31}
More examples
Hide additional examples
examples/complex_text.rs (line 21)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let dl = {
9        let mut builder = DisplayListBuilder::new(None);
10        let mut paint = Paint::default();
11        let paragraph = {
12            let ttx = TypographyContext::default(); // register any custom fonts if you want
13            let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
14            let mut pstyle = ParagraphStyle::default();
15            // you can set a custom font family if you want, but lets just use the system fonts
16            pstyle.set_font_size(48.0);
17            pstyle.set_font_weight(FontWeight::ExtraBold);
18            paint.set_color(Color::BLUEBERRY);
19            pstyle.set_foreground(&paint);
20            puilder.push_style(&pstyle);
21            puilder.add_text("HELLO EVERYONE");
22            puilder.build(600.0).unwrap()
23        };
24
25        paint.set_color(Color::BLACK); // clear with black first
26        builder.draw_paint(&paint);
27        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
28        builder.build().unwrap()
29    };
30    framework.enter_event_loop(Some(dl), None);
31}
examples/line_metrics.rs (line 19)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let mut paint = Paint::default(); // paint object to reuse
9    let paragraph = {
10        let ttx = TypographyContext::default(); // register any custom fonts if you want
11        let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
12        let mut pstyle = ParagraphStyle::default();
13        // you can set a custom font family if you want, but lets just use the system fonts
14        pstyle.set_font_size(48.0);
15        pstyle.set_font_weight(FontWeight::ExtraBold);
16        paint.set_color(Color::BLUEBERRY);
17        pstyle.set_foreground(&paint);
18        puilder.push_style(&pstyle);
19        puilder.add_text("HELLO EVERYONE");
20        puilder.build(600.0).unwrap()
21    };
22    let metrics = paragraph.get_line_metrics().unwrap();
23    dbg!(metrics.get_width(0));
24    dbg!(metrics.get_height(0));
25    dbg!(metrics.get_ascent(0));
26    dbg!(metrics.get_descent(0));
27    dbg!(metrics.get_baseline(0));
28    dbg!(metrics.get_left(0));
29    dbg!(metrics.get_unscaled_ascent(0));
30    dbg!(metrics.get_code_unit_start_index_utf16(0));
31
32    let dl = {
33        let mut builder = DisplayListBuilder::new(None);
34        paint.set_color(Color::BLACK); // clear with black first
35        builder.draw_paint(&paint);
36        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
37        builder.build().unwrap()
38    };
39    framework.enter_event_loop(Some(dl), None);
40}
examples/common.rs (line 150)
75    pub fn enter_event_loop(
76        mut self,
77        dl: Option<DisplayList>,
78        mut user_callback: Option<UserCallback>,
79    ) {
80        let mut previous_instant = std::time::Instant::now();
81        let mut current_frame = 0;
82        let mut fps = 0;
83        let mut vsync = true;
84        // enter event loop
85        while !self.window.should_close() {
86            {
87                // record fps
88                if previous_instant.elapsed().as_secs_f64() >= 1.0 {
89                    fps = current_frame;
90                    current_frame = 0;
91                    previous_instant = std::time::Instant::now();
92                }
93                current_frame += 1;
94            }
95            self.events.clear();
96            // check events
97            self.gtx.poll_events();
98            for (_, event) in flush_messages(&self.receiver) {
99                match &event {
100                    WindowEvent::Close => {
101                        self.window.set_should_close(true);
102                    }
103                    WindowEvent::FramebufferSize(w, h) => {
104                        unsafe {
105                            self.glow_ctx.viewport(0, 0, *w, *h);
106                        }
107                        println!("window resized to {}x{}", w, h);
108                    }
109                    WindowEvent::Key(Key::Space, _, Action::Release, _) => {
110                        vsync = !vsync;
111                        println!("setting vsync to {vsync}");
112
113                        self.gtx.set_swap_interval(if vsync {
114                            SwapInterval::Sync(1)
115                        } else {
116                            SwapInterval::None
117                        });
118                    }
119                    _ => {}
120                }
121                self.events.push(event);
122            }
123
124            let (width, height) = self.window.get_framebuffer_size();
125            // init surface by wrapping default framebuffer (fbo = 0)
126            let mut surface = unsafe {
127                self.itx.wrap_fbo(
128                    0,
129                    PixelFormat::RGBA8888,
130                    ISize::new(width.into(), height.into()),
131                )
132            }
133            .expect("failed to wrap window's framebuffer");
134            let mut dl_builder = DisplayListBuilder::new(Some(&Rect::from_size(
135                [width as f32, height as f32].into(),
136            )));
137
138            if let Some(dl) = dl.as_ref() {
139                dl_builder.draw_display_list(dl, 1.0);
140            }
141            // call user callback
142            if let Some(cb) = user_callback.as_mut() {
143                if let Some(display_list) = cb(&mut self) {
144                    dl_builder.draw_display_list(&display_list, 1.0);
145                }
146            }
147            {
148                let mut para_builder = ParagraphBuilder::new(&self.ttx).unwrap();
149                para_builder.push_style(&self.style);
150                para_builder.add_text(&format!("avg fps: {fps}"));
151                let para = para_builder.build(1000.0).unwrap();
152                dl_builder.draw_paragraph(&para, Point::origin());
153            }
154            surface
155                .draw_display_list(&dl_builder.build().unwrap())
156                .unwrap();
157
158            // submit frame and wait for vsync
159            self.window.swap_buffers();
160        }
161    }
Source

pub fn build(self, width: f32) -> Option<Paragraph>

Layout and build a new paragraph using the specified width. The resulting paragraph is immutable. The paragraph builder must be discarded and a new one created to build more paragraphs.

  • width The paragraph width.

@return The paragraph if one can be created, NULL otherwise.

Examples found in repository?
examples/basic_text.rs (line 22)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let dl = {
9        let mut builder = DisplayListBuilder::new(None);
10        let mut paint = Paint::default();
11        let paragraph = {
12            let ttx = TypographyContext::default(); // register any custom fonts if you want
13            let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
14            let mut pstyle = ParagraphStyle::default();
15            // you can set a custom font family if you want, but lets just use the system fonts
16            pstyle.set_font_size(48.0);
17            pstyle.set_font_weight(FontWeight::ExtraBold);
18            paint.set_color(Color::BLUEBERRY);
19            pstyle.set_foreground(&paint);
20            puilder.push_style(&pstyle);
21            puilder.add_text("HELLO EVERYONE");
22            puilder.build(600.0).unwrap()
23        };
24
25        paint.set_color(Color::BLACK); // clear with black first
26        builder.draw_paint(&paint);
27        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
28        builder.build().unwrap()
29    };
30    framework.enter_event_loop(Some(dl), None);
31}
More examples
Hide additional examples
examples/complex_text.rs (line 22)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let dl = {
9        let mut builder = DisplayListBuilder::new(None);
10        let mut paint = Paint::default();
11        let paragraph = {
12            let ttx = TypographyContext::default(); // register any custom fonts if you want
13            let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
14            let mut pstyle = ParagraphStyle::default();
15            // you can set a custom font family if you want, but lets just use the system fonts
16            pstyle.set_font_size(48.0);
17            pstyle.set_font_weight(FontWeight::ExtraBold);
18            paint.set_color(Color::BLUEBERRY);
19            pstyle.set_foreground(&paint);
20            puilder.push_style(&pstyle);
21            puilder.add_text("HELLO EVERYONE");
22            puilder.build(600.0).unwrap()
23        };
24
25        paint.set_color(Color::BLACK); // clear with black first
26        builder.draw_paint(&paint);
27        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
28        builder.build().unwrap()
29    };
30    framework.enter_event_loop(Some(dl), None);
31}
examples/line_metrics.rs (line 20)
4fn main() {
5    let framework = common::SdlGlImpellerFrameWork::new();
6    // if you want to do any initialization before event loop,
7    // this is the place for that.
8    let mut paint = Paint::default(); // paint object to reuse
9    let paragraph = {
10        let ttx = TypographyContext::default(); // register any custom fonts if you want
11        let mut puilder = ParagraphBuilder::new(&ttx).unwrap();
12        let mut pstyle = ParagraphStyle::default();
13        // you can set a custom font family if you want, but lets just use the system fonts
14        pstyle.set_font_size(48.0);
15        pstyle.set_font_weight(FontWeight::ExtraBold);
16        paint.set_color(Color::BLUEBERRY);
17        pstyle.set_foreground(&paint);
18        puilder.push_style(&pstyle);
19        puilder.add_text("HELLO EVERYONE");
20        puilder.build(600.0).unwrap()
21    };
22    let metrics = paragraph.get_line_metrics().unwrap();
23    dbg!(metrics.get_width(0));
24    dbg!(metrics.get_height(0));
25    dbg!(metrics.get_ascent(0));
26    dbg!(metrics.get_descent(0));
27    dbg!(metrics.get_baseline(0));
28    dbg!(metrics.get_left(0));
29    dbg!(metrics.get_unscaled_ascent(0));
30    dbg!(metrics.get_code_unit_start_index_utf16(0));
31
32    let dl = {
33        let mut builder = DisplayListBuilder::new(None);
34        paint.set_color(Color::BLACK); // clear with black first
35        builder.draw_paint(&paint);
36        builder.draw_paragraph(&paragraph, Point::new(100.0, 100.0));
37        builder.build().unwrap()
38    };
39    framework.enter_event_loop(Some(dl), None);
40}
examples/common.rs (line 151)
75    pub fn enter_event_loop(
76        mut self,
77        dl: Option<DisplayList>,
78        mut user_callback: Option<UserCallback>,
79    ) {
80        let mut previous_instant = std::time::Instant::now();
81        let mut current_frame = 0;
82        let mut fps = 0;
83        let mut vsync = true;
84        // enter event loop
85        while !self.window.should_close() {
86            {
87                // record fps
88                if previous_instant.elapsed().as_secs_f64() >= 1.0 {
89                    fps = current_frame;
90                    current_frame = 0;
91                    previous_instant = std::time::Instant::now();
92                }
93                current_frame += 1;
94            }
95            self.events.clear();
96            // check events
97            self.gtx.poll_events();
98            for (_, event) in flush_messages(&self.receiver) {
99                match &event {
100                    WindowEvent::Close => {
101                        self.window.set_should_close(true);
102                    }
103                    WindowEvent::FramebufferSize(w, h) => {
104                        unsafe {
105                            self.glow_ctx.viewport(0, 0, *w, *h);
106                        }
107                        println!("window resized to {}x{}", w, h);
108                    }
109                    WindowEvent::Key(Key::Space, _, Action::Release, _) => {
110                        vsync = !vsync;
111                        println!("setting vsync to {vsync}");
112
113                        self.gtx.set_swap_interval(if vsync {
114                            SwapInterval::Sync(1)
115                        } else {
116                            SwapInterval::None
117                        });
118                    }
119                    _ => {}
120                }
121                self.events.push(event);
122            }
123
124            let (width, height) = self.window.get_framebuffer_size();
125            // init surface by wrapping default framebuffer (fbo = 0)
126            let mut surface = unsafe {
127                self.itx.wrap_fbo(
128                    0,
129                    PixelFormat::RGBA8888,
130                    ISize::new(width.into(), height.into()),
131                )
132            }
133            .expect("failed to wrap window's framebuffer");
134            let mut dl_builder = DisplayListBuilder::new(Some(&Rect::from_size(
135                [width as f32, height as f32].into(),
136            )));
137
138            if let Some(dl) = dl.as_ref() {
139                dl_builder.draw_display_list(dl, 1.0);
140            }
141            // call user callback
142            if let Some(cb) = user_callback.as_mut() {
143                if let Some(display_list) = cb(&mut self) {
144                    dl_builder.draw_display_list(&display_list, 1.0);
145                }
146            }
147            {
148                let mut para_builder = ParagraphBuilder::new(&self.ttx).unwrap();
149                para_builder.push_style(&self.style);
150                para_builder.add_text(&format!("avg fps: {fps}"));
151                let para = para_builder.build(1000.0).unwrap();
152                dl_builder.draw_paragraph(&para, Point::origin());
153            }
154            surface
155                .draw_display_list(&dl_builder.build().unwrap())
156                .unwrap();
157
158            // submit frame and wait for vsync
159            self.window.swap_buffers();
160        }
161    }

Trait Implementations§

Source§

impl Debug for ParagraphBuilder

Source§

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

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

impl Drop for ParagraphBuilder

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

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> 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, 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.