[go: up one dir, main page]

FontDescriptor

Struct FontDescriptor 

Source
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: FontFamily

The font’s FontFamily.

§size: f64

The font’s size.

§weight: FontWeight

The font’s FontWeight.

§style: FontStyle

The font’s FontStyle.

Implementations§

Source§

impl FontDescriptor

Source

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
Hide additional 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    }
Source

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
Hide additional 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    }
Source

pub const fn with_weight(self, weight: FontWeight) -> Self

Buider-style method to set the descriptor’s FontWeight.

Source

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

Source§

fn clone(&self) -> FontDescriptor

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Data for FontDescriptor

Source§

fn same(&self, other: &Self) -> bool

Determine whether two values are the same. Read more
Source§

impl Debug for FontDescriptor

Source§

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

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

impl Default for FontDescriptor

Source§

fn default() -> Self

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

impl From<FontDescriptor> for Value

Source§

fn from(val: FontDescriptor) -> Value

Converts to this type from the input type.
Source§

impl PartialEq for FontDescriptor

Source§

fn eq(&self, other: &FontDescriptor) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl ValueType for FontDescriptor

Source§

fn try_from_value(value: &Value) -> Result<Self, ValueTypeError>

Attempt to convert the generic Value into this type.
Source§

impl StructuralPartialEq for FontDescriptor

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> AnyEq for T
where T: Any + PartialEq,

Source§

fn equals(&self, other: &(dyn Any + 'static)) -> bool

Source§

fn as_any(&self) -> &(dyn Any + 'static)

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> RoundFrom<T> for T

Source§

fn round_from(x: T) -> T

Performs the conversion.
Source§

impl<T, U> RoundInto<U> for T
where U: RoundFrom<T>,

Source§

fn round_into(self) -> U

Performs the conversion.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more