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
impl ParagraphBuilder
Sourcepub fn new(context: &TypographyContext) -> Option<ParagraphBuilder>
pub fn new(context: &TypographyContext) -> Option<ParagraphBuilder>
Create a new paragraph builder.
@return The paragraph builder.
Examples found in repository?
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(¶graph, Point::new(100.0, 100.0));
28 builder.build().unwrap()
29 };
30 framework.enter_event_loop(Some(dl), None);
31}More examples
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(¶graph, Point::new(100.0, 100.0));
28 builder.build().unwrap()
29 };
30 framework.enter_event_loop(Some(dl), None);
31}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(¶graph, Point::new(100.0, 100.0));
37 builder.build().unwrap()
38 };
39 framework.enter_event_loop(Some(dl), None);
40}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(¶, 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 }Sourcepub fn push_style(&mut self, style: &ParagraphStyle) -> &mut Self
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?
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(¶graph, Point::new(100.0, 100.0));
28 builder.build().unwrap()
29 };
30 framework.enter_event_loop(Some(dl), None);
31}More examples
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(¶graph, Point::new(100.0, 100.0));
28 builder.build().unwrap()
29 };
30 framework.enter_event_loop(Some(dl), None);
31}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(¶graph, Point::new(100.0, 100.0));
37 builder.build().unwrap()
38 };
39 framework.enter_event_loop(Some(dl), None);
40}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(¶, 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 }Sourcepub fn pop_style(&mut self) -> &mut Self
pub fn pop_style(&mut self) -> &mut Self
Pop a previously pushed paragraph style from the paragraph style stack.
Sourcepub fn add_text(&mut self, text: &str) -> &mut Self
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?
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(¶graph, Point::new(100.0, 100.0));
28 builder.build().unwrap()
29 };
30 framework.enter_event_loop(Some(dl), None);
31}More examples
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(¶graph, Point::new(100.0, 100.0));
28 builder.build().unwrap()
29 };
30 framework.enter_event_loop(Some(dl), None);
31}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(¶graph, Point::new(100.0, 100.0));
37 builder.build().unwrap()
38 };
39 framework.enter_event_loop(Some(dl), None);
40}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(¶, 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 }Sourcepub fn build(self, width: f32) -> Option<Paragraph>
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?
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(¶graph, Point::new(100.0, 100.0));
28 builder.build().unwrap()
29 };
30 framework.enter_event_loop(Some(dl), None);
31}More examples
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(¶graph, Point::new(100.0, 100.0));
28 builder.build().unwrap()
29 };
30 framework.enter_event_loop(Some(dl), None);
31}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(¶graph, Point::new(100.0, 100.0));
37 builder.build().unwrap()
38 };
39 framework.enter_event_loop(Some(dl), None);
40}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(¶, 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 }