pub struct FontDescriptor {
pub family: FontFamily,
pub size: f64,
pub weight: FontWeight,
pub style: FontStyle,
}Expand description
A collection of attributes that describe a font.
This is provided as a convenience; library consumers may wish to have a single type that represents a specific font face at a specific size.
Fields§
§family: FontFamilyThe font’s FontFamily.
size: f64The font’s size.
weight: FontWeightThe font’s FontWeight.
style: FontStyleThe font’s FontStyle.
Implementations§
Source§impl FontDescriptor
impl FontDescriptor
Sourcepub const fn new(family: FontFamily) -> Self
pub const fn new(family: FontFamily) -> Self
Create a new descriptor with the provided FontFamily.
Examples found in repository?
examples/styled_text.rs (line 107)
72fn ui_builder() -> impl Widget<AppData> {
73 let my_painter = Painter::new(|ctx, _, _| {
74 let bounds = ctx.size().to_rect();
75 if ctx.is_hot() {
76 ctx.fill(bounds, &Color::rgba8(0, 0, 0, 128));
77 }
78
79 if ctx.is_active() {
80 ctx.stroke(bounds, &Color::WHITE, 2.0);
81 }
82 });
83
84 // This is Druid's default text style.
85 // It's set by theme::LABEL_COLOR and theme::UI_FONT
86 let label =
87 Label::new(|data: &String, _env: &_| format!("Default: {data}")).lens(AppData::text);
88
89 // The text_color, text_size, and font builder methods can override the
90 // defaults provided by the theme by passing in a Key or a concrete value.
91 //
92 // In this example, text_color receives a Key from the theme, text_size
93 // gets a custom key which we set with the env_scope wrapper, and the
94 // default font key (theme::FONT_NAME) is overridden in the env_scope
95 // wrapper. (Like text_color and text_size, the font can be set using the
96 // with_font builder method, but overriding here makes it easy to fall back
97 // to the default font)
98 let styled_label = Label::new(|data: &AppData, _env: &_| format!("{data}"))
99 .with_text_color(theme::PRIMARY_LIGHT)
100 .with_font(MY_CUSTOM_FONT)
101 .background(my_painter)
102 .on_click(|_, data, _| {
103 data.size *= 1.1;
104 })
105 .env_scope(|env: &mut druid::Env, data: &AppData| {
106 let new_font = if data.mono {
107 FontDescriptor::new(FontFamily::MONOSPACE)
108 } else {
109 FontDescriptor::new(FontFamily::SYSTEM_UI)
110 }
111 .with_size(data.size);
112 env.set(MY_CUSTOM_FONT, new_font);
113 });
114
115 let labels = Scroll::new(
116 Flex::column()
117 .cross_axis_alignment(CrossAxisAlignment::Start)
118 .with_child(label)
119 .with_default_spacer()
120 .with_child(styled_label),
121 )
122 .expand_height()
123 .fix_width(COLUMN_WIDTH);
124
125 let stepper = Stepper::new()
126 .with_range(0.0, 100.0)
127 .with_step(1.0)
128 .with_wraparound(false)
129 .lens(AppData::size);
130
131 // TODO: Replace Parse usage with TextBox::with_formatter
132 #[allow(deprecated)]
133 let stepper_textbox = LensWrap::new(
134 Parse::new(TextBox::new()),
135 AppData::size.map(|x| Some(*x), |x, y| *x = y.unwrap_or(24.0)),
136 );
137
138 let mono_checkbox = Checkbox::new("Monospace").lens(AppData::mono);
139 let stepper_row = Flex::row()
140 .with_child(stepper_textbox)
141 .with_child(stepper)
142 .with_default_spacer()
143 .with_child(mono_checkbox);
144
145 let input = TextBox::multiline()
146 .with_placeholder("Your sample text here :)")
147 .fix_width(COLUMN_WIDTH)
148 .fix_height(140.0)
149 .lens(AppData::text);
150
151 Flex::column()
152 .main_axis_alignment(MainAxisAlignment::Center)
153 .with_default_spacer()
154 .with_flex_child(labels, 1.0)
155 .with_default_spacer()
156 .with_child(input)
157 .with_default_spacer()
158 .with_child(stepper_row)
159 .with_default_spacer()
160}More examples
examples/custom_widget.rs (line 119)
77 fn paint(&mut self, ctx: &mut PaintCtx, data: &String, env: &Env) {
78 // Clear the whole widget with the color of your choice
79 // (ctx.size() returns the size of the layout rect we're painting in)
80 // Note: ctx also has a `clear` method, but that clears the whole context,
81 // and we only want to clear this widget's area.
82 let size = ctx.size();
83 let rect = size.to_rect();
84 ctx.fill(rect, &Color::WHITE);
85
86 // We can paint with a Z index, this indicates that this code will be run
87 // after the rest of the painting. Painting with z-index is done in order,
88 // so first everything with z-index 1 is painted and then with z-index 2 etc.
89 // As you can see this(red) curve is drawn on top of the green curve
90 ctx.paint_with_z_index(1, move |ctx| {
91 let mut path = BezPath::new();
92 path.move_to((0.0, size.height));
93 path.quad_to((40.0, 50.0), (size.width, 0.0));
94 // Create a color
95 let stroke_color = Color::rgb8(128, 0, 0);
96 // Stroke the path with thickness 1.0
97 ctx.stroke(path, &stroke_color, 5.0);
98 });
99
100 // Create an arbitrary bezier path
101 let mut path = BezPath::new();
102 path.move_to(Point::ORIGIN);
103 path.quad_to((40.0, 50.0), (size.width, size.height));
104 // Create a color
105 let stroke_color = Color::rgb8(0, 128, 0);
106 // Stroke the path with thickness 5.0
107 ctx.stroke(path, &stroke_color, 5.0);
108
109 // Rectangles: the path for practical people
110 let rect = Rect::from_origin_size((10.0, 10.0), (100.0, 100.0));
111 // Note the Color:rgba8 which includes an alpha channel (7F in this case)
112 let fill_color = Color::rgba8(0x00, 0x00, 0x00, 0x7F);
113 ctx.fill(rect, &fill_color);
114
115 // Text is easy; in real use TextLayout should either be stored in the
116 // widget and reused, or a label child widget to manage it all.
117 // This is one way of doing it, you can also use a builder-style way.
118 let mut layout = TextLayout::<String>::from_text(data);
119 layout.set_font(FontDescriptor::new(FontFamily::SERIF).with_size(24.0));
120 layout.set_text_color(fill_color);
121 layout.rebuild_if_needed(ctx.text(), env);
122
123 // Let's rotate our text slightly. First we save our current (default) context:
124 ctx.with_save(|ctx| {
125 // Now we can rotate the context (or set a clip path, for instance):
126 // This makes it so that anything drawn after this (in the closure) is
127 // transformed.
128 // The transformation is in radians, but be aware it transforms the canvas,
129 // not just the part you are drawing. So we draw at (80.0, 40.0) on the rotated
130 // canvas, this is NOT the same position as (80.0, 40.0) on the original canvas.
131 ctx.transform(Affine::rotate(std::f64::consts::FRAC_PI_4));
132 layout.draw(ctx, (80.0, 40.0));
133 });
134 // When we exit with_save, the original context's rotation is restored
135
136 // This is the builder-style way of drawing text.
137 let text = ctx.text();
138 let layout = text
139 .new_text_layout(data.clone())
140 .font(FontFamily::SERIF, 24.0)
141 .text_color(Color::rgb8(128, 0, 0))
142 .build()
143 .unwrap();
144 ctx.draw_text(&layout, (100.0, 25.0));
145
146 // Let's burn some CPU to make a (partially transparent) image buffer
147 let image_data = make_image_data(256, 256);
148 let image = ctx
149 .make_image(256, 256, &image_data, ImageFormat::RgbaSeparate)
150 .unwrap();
151 // The image is automatically scaled to fit the rect you pass to draw_image
152 ctx.draw_image(&image, size.to_rect(), InterpolationMode::Bilinear);
153 }Sourcepub const fn with_size(self, size: f64) -> Self
pub const fn with_size(self, size: f64) -> Self
Buider-style method to set the descriptor’s font size.
Examples found in repository?
examples/event_viewer.rs (line 341)
331pub fn main() {
332 //describe the main window
333 let main_window = WindowDesc::new(build_root_widget())
334 .title("Event Viewer")
335 .window_size((760.0, 680.0));
336
337 //start the application
338 AppLauncher::with_window(main_window)
339 .log_to_console()
340 .configure_env(|env, _| {
341 env.set(theme::UI_FONT, FontDescriptor::default().with_size(12.0));
342 env.set(theme::TEXT_COLOR, TEXT_COLOR);
343 env.set(theme::WIDGET_PADDING_HORIZONTAL, 2.0);
344 env.set(theme::WIDGET_PADDING_VERTICAL, 2.0);
345 })
346 .launch(AppState {
347 text_input: String::new(),
348 events: Arc::new(Vec::new()),
349 })
350 .expect("Failed to launch application");
351}More examples
examples/styled_text.rs (line 111)
72fn ui_builder() -> impl Widget<AppData> {
73 let my_painter = Painter::new(|ctx, _, _| {
74 let bounds = ctx.size().to_rect();
75 if ctx.is_hot() {
76 ctx.fill(bounds, &Color::rgba8(0, 0, 0, 128));
77 }
78
79 if ctx.is_active() {
80 ctx.stroke(bounds, &Color::WHITE, 2.0);
81 }
82 });
83
84 // This is Druid's default text style.
85 // It's set by theme::LABEL_COLOR and theme::UI_FONT
86 let label =
87 Label::new(|data: &String, _env: &_| format!("Default: {data}")).lens(AppData::text);
88
89 // The text_color, text_size, and font builder methods can override the
90 // defaults provided by the theme by passing in a Key or a concrete value.
91 //
92 // In this example, text_color receives a Key from the theme, text_size
93 // gets a custom key which we set with the env_scope wrapper, and the
94 // default font key (theme::FONT_NAME) is overridden in the env_scope
95 // wrapper. (Like text_color and text_size, the font can be set using the
96 // with_font builder method, but overriding here makes it easy to fall back
97 // to the default font)
98 let styled_label = Label::new(|data: &AppData, _env: &_| format!("{data}"))
99 .with_text_color(theme::PRIMARY_LIGHT)
100 .with_font(MY_CUSTOM_FONT)
101 .background(my_painter)
102 .on_click(|_, data, _| {
103 data.size *= 1.1;
104 })
105 .env_scope(|env: &mut druid::Env, data: &AppData| {
106 let new_font = if data.mono {
107 FontDescriptor::new(FontFamily::MONOSPACE)
108 } else {
109 FontDescriptor::new(FontFamily::SYSTEM_UI)
110 }
111 .with_size(data.size);
112 env.set(MY_CUSTOM_FONT, new_font);
113 });
114
115 let labels = Scroll::new(
116 Flex::column()
117 .cross_axis_alignment(CrossAxisAlignment::Start)
118 .with_child(label)
119 .with_default_spacer()
120 .with_child(styled_label),
121 )
122 .expand_height()
123 .fix_width(COLUMN_WIDTH);
124
125 let stepper = Stepper::new()
126 .with_range(0.0, 100.0)
127 .with_step(1.0)
128 .with_wraparound(false)
129 .lens(AppData::size);
130
131 // TODO: Replace Parse usage with TextBox::with_formatter
132 #[allow(deprecated)]
133 let stepper_textbox = LensWrap::new(
134 Parse::new(TextBox::new()),
135 AppData::size.map(|x| Some(*x), |x, y| *x = y.unwrap_or(24.0)),
136 );
137
138 let mono_checkbox = Checkbox::new("Monospace").lens(AppData::mono);
139 let stepper_row = Flex::row()
140 .with_child(stepper_textbox)
141 .with_child(stepper)
142 .with_default_spacer()
143 .with_child(mono_checkbox);
144
145 let input = TextBox::multiline()
146 .with_placeholder("Your sample text here :)")
147 .fix_width(COLUMN_WIDTH)
148 .fix_height(140.0)
149 .lens(AppData::text);
150
151 Flex::column()
152 .main_axis_alignment(MainAxisAlignment::Center)
153 .with_default_spacer()
154 .with_flex_child(labels, 1.0)
155 .with_default_spacer()
156 .with_child(input)
157 .with_default_spacer()
158 .with_child(stepper_row)
159 .with_default_spacer()
160}examples/custom_widget.rs (line 119)
77 fn paint(&mut self, ctx: &mut PaintCtx, data: &String, env: &Env) {
78 // Clear the whole widget with the color of your choice
79 // (ctx.size() returns the size of the layout rect we're painting in)
80 // Note: ctx also has a `clear` method, but that clears the whole context,
81 // and we only want to clear this widget's area.
82 let size = ctx.size();
83 let rect = size.to_rect();
84 ctx.fill(rect, &Color::WHITE);
85
86 // We can paint with a Z index, this indicates that this code will be run
87 // after the rest of the painting. Painting with z-index is done in order,
88 // so first everything with z-index 1 is painted and then with z-index 2 etc.
89 // As you can see this(red) curve is drawn on top of the green curve
90 ctx.paint_with_z_index(1, move |ctx| {
91 let mut path = BezPath::new();
92 path.move_to((0.0, size.height));
93 path.quad_to((40.0, 50.0), (size.width, 0.0));
94 // Create a color
95 let stroke_color = Color::rgb8(128, 0, 0);
96 // Stroke the path with thickness 1.0
97 ctx.stroke(path, &stroke_color, 5.0);
98 });
99
100 // Create an arbitrary bezier path
101 let mut path = BezPath::new();
102 path.move_to(Point::ORIGIN);
103 path.quad_to((40.0, 50.0), (size.width, size.height));
104 // Create a color
105 let stroke_color = Color::rgb8(0, 128, 0);
106 // Stroke the path with thickness 5.0
107 ctx.stroke(path, &stroke_color, 5.0);
108
109 // Rectangles: the path for practical people
110 let rect = Rect::from_origin_size((10.0, 10.0), (100.0, 100.0));
111 // Note the Color:rgba8 which includes an alpha channel (7F in this case)
112 let fill_color = Color::rgba8(0x00, 0x00, 0x00, 0x7F);
113 ctx.fill(rect, &fill_color);
114
115 // Text is easy; in real use TextLayout should either be stored in the
116 // widget and reused, or a label child widget to manage it all.
117 // This is one way of doing it, you can also use a builder-style way.
118 let mut layout = TextLayout::<String>::from_text(data);
119 layout.set_font(FontDescriptor::new(FontFamily::SERIF).with_size(24.0));
120 layout.set_text_color(fill_color);
121 layout.rebuild_if_needed(ctx.text(), env);
122
123 // Let's rotate our text slightly. First we save our current (default) context:
124 ctx.with_save(|ctx| {
125 // Now we can rotate the context (or set a clip path, for instance):
126 // This makes it so that anything drawn after this (in the closure) is
127 // transformed.
128 // The transformation is in radians, but be aware it transforms the canvas,
129 // not just the part you are drawing. So we draw at (80.0, 40.0) on the rotated
130 // canvas, this is NOT the same position as (80.0, 40.0) on the original canvas.
131 ctx.transform(Affine::rotate(std::f64::consts::FRAC_PI_4));
132 layout.draw(ctx, (80.0, 40.0));
133 });
134 // When we exit with_save, the original context's rotation is restored
135
136 // This is the builder-style way of drawing text.
137 let text = ctx.text();
138 let layout = text
139 .new_text_layout(data.clone())
140 .font(FontFamily::SERIF, 24.0)
141 .text_color(Color::rgb8(128, 0, 0))
142 .build()
143 .unwrap();
144 ctx.draw_text(&layout, (100.0, 25.0));
145
146 // Let's burn some CPU to make a (partially transparent) image buffer
147 let image_data = make_image_data(256, 256);
148 let image = ctx
149 .make_image(256, 256, &image_data, ImageFormat::RgbaSeparate)
150 .unwrap();
151 // The image is automatically scaled to fit the rect you pass to draw_image
152 ctx.draw_image(&image, size.to_rect(), InterpolationMode::Bilinear);
153 }Sourcepub const fn with_weight(self, weight: FontWeight) -> Self
pub const fn with_weight(self, weight: FontWeight) -> Self
Buider-style method to set the descriptor’s FontWeight.
Sourcepub const fn with_style(self, style: FontStyle) -> Self
pub const fn with_style(self, style: FontStyle) -> Self
Buider-style method to set the descriptor’s FontStyle.
Trait Implementations§
Source§impl Clone for FontDescriptor
impl Clone for FontDescriptor
Source§fn clone(&self) -> FontDescriptor
fn clone(&self) -> FontDescriptor
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Data for FontDescriptor
impl Data for FontDescriptor
Source§impl Debug for FontDescriptor
impl Debug for FontDescriptor
Source§impl Default for FontDescriptor
impl Default for FontDescriptor
Source§impl From<FontDescriptor> for Value
impl From<FontDescriptor> for Value
Source§fn from(val: FontDescriptor) -> Value
fn from(val: FontDescriptor) -> Value
Converts to this type from the input type.
Source§impl PartialEq for FontDescriptor
impl PartialEq for FontDescriptor
Source§impl ValueType for FontDescriptor
impl ValueType for FontDescriptor
Source§fn try_from_value(value: &Value) -> Result<Self, ValueTypeError>
fn try_from_value(value: &Value) -> Result<Self, ValueTypeError>
Attempt to convert the generic
Value into this type.impl StructuralPartialEq for FontDescriptor
Auto Trait Implementations§
impl Freeze for FontDescriptor
impl RefUnwindSafe for FontDescriptor
impl Send for FontDescriptor
impl Sync for FontDescriptor
impl Unpin for FontDescriptor
impl UnwindSafe for FontDescriptor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T, U> RoundInto<U> for Twhere
U: RoundFrom<T>,
impl<T, U> RoundInto<U> for Twhere
U: RoundFrom<T>,
Source§fn round_into(self) -> U
fn round_into(self) -> U
Performs the conversion.