Make TextStyle !Copy

This commit is contained in:
Emil Ernerfeldt 2022-01-22 18:02:02 +01:00
parent 0df77d9074
commit 4f98f26fda
21 changed files with 126 additions and 92 deletions

View file

@ -414,7 +414,8 @@ impl SubMenuButton {
let button_padding = ui.spacing().button_padding; let button_padding = ui.spacing().button_padding;
let total_extra = button_padding + button_padding; let total_extra = button_padding + button_padding;
let text_available_width = ui.available_width() - total_extra.x; let text_available_width = ui.available_width() - total_extra.x;
let text_galley = text.into_galley(ui, Some(true), text_available_width, text_style); let text_galley =
text.into_galley(ui, Some(true), text_available_width, text_style.clone());
let icon_available_width = text_available_width - text_galley.size().x; let icon_available_width = text_available_width - text_galley.size().x;
let icon_galley = icon.into_galley(ui, Some(true), icon_available_width, text_style); let icon_galley = icon.into_galley(ui, Some(true), icon_available_width, text_style);

View file

@ -581,8 +581,9 @@ impl Style {
crate::Grid::new("_options").show(ui, |ui| { crate::Grid::new("_options").show(ui, |ui| {
ui.label("Default body text style:"); ui.label("Default body text style:");
ui.horizontal(|ui| { ui.horizontal(|ui| {
for &style in &[TextStyle::Body, TextStyle::Monospace] { for style in [TextStyle::Body, TextStyle::Monospace] {
let text = crate::RichText::new(format!("{:?}", style)).text_style(style); let text =
crate::RichText::new(format!("{:?}", style)).text_style(style.clone());
ui.radio_value(body_text_style, style, text); ui.radio_value(body_text_style, style, text);
} }
}); });
@ -597,7 +598,8 @@ impl Style {
.show_ui(ui, |ui| { .show_ui(ui, |ui| {
ui.selectable_value(override_text_style, None, "None"); ui.selectable_value(override_text_style, None, "None");
for style in TextStyle::all() { for style in TextStyle::all() {
let text = crate::RichText::new(format!("{:?}", style)).text_style(style); let text =
crate::RichText::new(format!("{:?}", style)).text_style(style.clone());
ui.selectable_value(override_text_style, Some(style), text); ui.selectable_value(override_text_style, Some(style), text);
} }
}); });

View file

@ -173,9 +173,10 @@ impl RichText {
pub fn font_height(&self, ctx: &Context) -> f32 { pub fn font_height(&self, ctx: &Context) -> f32 {
let text_style = self let text_style = self
.text_style .text_style
.or(ctx.style().override_text_style) .clone()
.unwrap_or(ctx.style().body_text_style); .or_else(|| ctx.style().override_text_style.clone())
ctx.fonts().row_height(text_style) .unwrap_or_else(|| ctx.style().body_text_style.clone());
ctx.fonts().row_height(&text_style)
} }
fn into_text_job( fn into_text_job(
@ -205,7 +206,7 @@ impl RichText {
let text_color = text_color.unwrap_or(crate::Color32::TEMPORARY_COLOR); let text_color = text_color.unwrap_or(crate::Color32::TEMPORARY_COLOR);
let text_style = text_style let text_style = text_style
.or(style.override_text_style) .or_else(|| style.override_text_style.clone())
.unwrap_or(default_text_style); .unwrap_or(default_text_style);
let mut background_color = background_color; let mut background_color = background_color;

View file

@ -82,9 +82,9 @@ impl Label {
} }
let valign = ui.layout().vertical_align(); let valign = ui.layout().vertical_align();
let mut text_job = self let mut text_job =
.text self.text
.into_text_job(ui.style(), ui.style().body_text_style, valign); .into_text_job(ui.style(), ui.style().body_text_style.clone(), valign);
let should_wrap = self.wrap.unwrap_or_else(|| ui.wrap_text()); let should_wrap = self.wrap.unwrap_or_else(|| ui.wrap_text());
let available_width = ui.available_width(); let available_width = ui.available_width();

View file

@ -684,7 +684,7 @@ impl PlotItem for Text {
let pos = transform.position_from_value(&self.position); let pos = transform.position_from_value(&self.position);
let galley = ui let galley = ui
.fonts() .fonts()
.layout_no_wrap(self.text.clone(), self.style, color); .layout_no_wrap(self.text.clone(), self.style.clone(), color);
let rect = self let rect = self
.anchor .anchor
.anchor_rect(Rect::from_min_size(pos, galley.size())); .anchor_rect(Rect::from_min_size(pos, galley.size()));

View file

@ -29,7 +29,7 @@ impl Corner {
} }
/// The configuration for a plot legend. /// The configuration for a plot legend.
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, PartialEq)]
pub struct Legend { pub struct Legend {
pub text_style: TextStyle, pub text_style: TextStyle,
pub background_alpha: f32, pub background_alpha: f32,
@ -89,9 +89,11 @@ impl LegendEntry {
hovered, hovered,
} = self; } = self;
let galley = let galley = ui.fonts().layout_delayed_color(
ui.fonts() text,
.layout_delayed_color(text, ui.style().body_text_style, f32::INFINITY); ui.style().body_text_style.clone(),
f32::INFINITY,
);
let icon_size = galley.size().y; let icon_size = galley.size().y;
let icon_spacing = icon_size / 5.0; let icon_spacing = icon_size / 5.0;
@ -236,7 +238,7 @@ impl Widget for &mut LegendWidget {
let mut legend_ui = ui.child_ui(legend_rect, layout); let mut legend_ui = ui.child_ui(legend_rect, layout);
legend_ui legend_ui
.scope(|ui| { .scope(|ui| {
ui.style_mut().body_text_style = config.text_style; ui.style_mut().body_text_style = config.text_style.clone();
let background_frame = Frame { let background_frame = Frame {
margin: vec2(8.0, 4.0), margin: vec2(8.0, 4.0),
corner_radius: ui.style().visuals.window_corner_radius, corner_radius: ui.style().visuals.window_corner_radius,

View file

@ -741,7 +741,7 @@ impl PreparedPlot {
let color = color_from_alpha(ui, text_alpha); let color = color_from_alpha(ui, text_alpha);
let text = emath::round_to_decimals(value_main, 5).to_string(); // hack let text = emath::round_to_decimals(value_main, 5).to_string(); // hack
let galley = ui.painter().layout_no_wrap(text, text_style, color); let galley = ui.painter().layout_no_wrap(text, text_style.clone(), color);
let mut text_pos = pos_in_gui + vec2(1.0, -galley.size().y); let mut text_pos = pos_in_gui + vec2(1.0, -galley.size().y);

View file

@ -469,7 +469,7 @@ impl<'a> Slider<'a> {
let text_style = TextStyle::Button; let text_style = TextStyle::Button;
let perpendicular = ui let perpendicular = ui
.fonts() .fonts()
.row_height(text_style) .row_height(&text_style)
.at_least(ui.spacing().interact_size.y); .at_least(ui.spacing().interact_size.y);
let slider_response = self.allocate_slider_space(ui, perpendicular); let slider_response = self.allocate_slider_space(ui, perpendicular);
self.slider_ui(ui, &slider_response); self.slider_ui(ui, &slider_response);

View file

@ -351,9 +351,9 @@ impl<'t> TextEdit<'t> {
let prev_text = text.as_ref().to_owned(); let prev_text = text.as_ref().to_owned();
let text_style = text_style let text_style = text_style
.or(ui.style().override_text_style) .or_else(|| ui.style().override_text_style.clone())
.unwrap_or_else(|| ui.style().body_text_style); .unwrap_or_else(|| ui.style().body_text_style.clone());
let row_height = ui.fonts().row_height(text_style); let row_height = ui.fonts().row_height(&text_style);
const MIN_WIDTH: f32 = 24.0; // Never make a `TextEdit` more narrow than this. const MIN_WIDTH: f32 = 24.0; // Never make a `TextEdit` more narrow than this.
let available_width = ui.available_width().at_least(MIN_WIDTH); let available_width = ui.available_width().at_least(MIN_WIDTH);
let desired_width = desired_width.unwrap_or_else(|| ui.spacing().text_edit_width); let desired_width = desired_width.unwrap_or_else(|| ui.spacing().text_edit_width);
@ -363,12 +363,13 @@ impl<'t> TextEdit<'t> {
desired_width.min(available_width) desired_width.min(available_width)
}; };
let text_style_clone = text_style.clone();
let mut default_layouter = move |ui: &Ui, text: &str, wrap_width: f32| { let mut default_layouter = move |ui: &Ui, text: &str, wrap_width: f32| {
let text = mask_if_password(password, text); let text = mask_if_password(password, text);
ui.fonts().layout_job(if multiline { ui.fonts().layout_job(if multiline {
LayoutJob::simple(text, text_style, text_color, wrap_width) LayoutJob::simple(text, text_style_clone.clone(), text_color, wrap_width)
} else { } else {
LayoutJob::simple_singleline(text, text_style, text_color) LayoutJob::simple_singleline(text, text_style_clone.clone(), text_color)
}) })
}; };

View file

@ -71,7 +71,7 @@ impl super::View for CodeEditor {
ui.collapsing("Theme", |ui| { ui.collapsing("Theme", |ui| {
ui.group(|ui| { ui.group(|ui| {
theme.ui(ui); theme.ui(ui);
theme.store_in_memory(ui.ctx()); theme.clone().store_in_memory(ui.ctx());
}); });
}); });

View file

@ -98,7 +98,7 @@ impl CodeExample {
); );
ui.horizontal(|ui| { ui.horizontal(|ui| {
let indentation = 8.0 * ui.fonts().glyph_width(egui::TextStyle::Monospace, ' '); let indentation = 8.0 * ui.fonts().glyph_width(&egui::TextStyle::Monospace, ' ');
let item_spacing = ui.spacing_mut().item_spacing; let item_spacing = ui.spacing_mut().item_spacing;
ui.add_space(indentation - item_spacing.x); ui.add_space(indentation - item_spacing.x);

View file

@ -55,7 +55,11 @@ impl super::View for FontBook {
.selected_text(format!("{:?}", self.text_style)) .selected_text(format!("{:?}", self.text_style))
.show_ui(ui, |ui| { .show_ui(ui, |ui| {
for style in egui::TextStyle::all() { for style in egui::TextStyle::all() {
ui.selectable_value(&mut self.text_style, style, format!("{:?}", style)); ui.selectable_value(
&mut self.text_style,
style.clone(),
format!("{:?}", style),
);
} }
}); });
@ -68,13 +72,16 @@ impl super::View for FontBook {
} }
}); });
let text_style = self.text_style; let text_style = self.text_style.clone();
let filter = &self.filter; let filter = &self.filter;
let named_chars = self.named_chars.entry(text_style).or_insert_with(|| { let named_chars = self
.named_chars
.entry(text_style.clone())
.or_insert_with(|| {
ui.fonts() ui.fonts()
.lock() .lock()
.fonts .fonts
.font_mut(text_style) .font_mut(&text_style)
.characters() .characters()
.iter() .iter()
.filter(|chr| !chr.is_whitespace() && !chr.is_ascii_control()) .filter(|chr| !chr.is_whitespace() && !chr.is_ascii_control())
@ -91,12 +98,14 @@ impl super::View for FontBook {
for (&chr, name) in named_chars { for (&chr, name) in named_chars {
if filter.is_empty() || name.contains(filter) || *filter == chr.to_string() { if filter.is_empty() || name.contains(filter) || *filter == chr.to_string() {
let button = egui::Button::new( let button = egui::Button::new(
egui::RichText::new(chr.to_string()).text_style(text_style), egui::RichText::new(chr.to_string()).text_style(text_style.clone()),
) )
.frame(false); .frame(false);
let tooltip_ui = |ui: &mut egui::Ui| { let tooltip_ui = |ui: &mut egui::Ui| {
ui.label(egui::RichText::new(chr.to_string()).text_style(text_style)); ui.label(
egui::RichText::new(chr.to_string()).text_style(text_style.clone()),
);
ui.label(format!("{}\nU+{:X}\n\nClick to copy", name, chr as u32)); ui.label(format!("{}\nU+{:X}\n\nClick to copy", name, chr as u32));
}; };

View file

@ -140,7 +140,7 @@ impl Widgets {
ui.horizontal_wrapped(|ui| { ui.horizontal_wrapped(|ui| {
// Trick so we don't have to add spaces in the text below: // Trick so we don't have to add spaces in the text below:
let width = ui.fonts().glyph_width(TextStyle::Body, ' '); let width = ui.fonts().glyph_width(&TextStyle::Body, ' ');
ui.spacing_mut().item_spacing.x = width; ui.spacing_mut().item_spacing.x = width;
ui.label(RichText::new("Text can have").color(Color32::from_rgb(110, 255, 110))); ui.label(RichText::new("Text can have").color(Color32::from_rgb(110, 255, 110)));

View file

@ -262,7 +262,11 @@ impl Widget for &mut LegendDemo {
ui.label("Text style:"); ui.label("Text style:");
ui.horizontal(|ui| { ui.horizontal(|ui| {
TextStyle::all().for_each(|style| { TextStyle::all().for_each(|style| {
ui.selectable_value(&mut config.text_style, style, format!("{:?}", style)); ui.selectable_value(
&mut config.text_style,
style.clone(),
format!("{:?}", style),
);
}); });
}); });
ui.end_row(); ui.end_row();
@ -284,7 +288,9 @@ impl Widget for &mut LegendDemo {
ui.end_row(); ui.end_row();
}); });
let legend_plot = Plot::new("legend_demo").legend(*config).data_aspect(1.0); let legend_plot = Plot::new("legend_demo")
.legend(config.clone())
.data_aspect(1.0);
legend_plot legend_plot
.show(ui, |plot_ui| { .show(ui, |plot_ui| {
plot_ui.line(LegendDemo::line_with_slope(0.5).name("lines")); plot_ui.line(LegendDemo::line_with_slope(0.5).name("lines"));

View file

@ -81,7 +81,7 @@ fn huge_content_lines(ui: &mut egui::Ui) {
ui.add_space(4.0); ui.add_space(4.0);
let text_style = TextStyle::Body; let text_style = TextStyle::Body;
let row_height = ui.fonts().row_height(text_style); let row_height = ui.fonts().row_height(&text_style);
let num_rows = 10_000; let num_rows = 10_000;
ScrollArea::vertical().auto_shrink([false; 2]).show_rows( ScrollArea::vertical().auto_shrink([false; 2]).show_rows(
ui, ui,
@ -102,7 +102,7 @@ fn huge_content_painter(ui: &mut egui::Ui) {
ui.add_space(4.0); ui.add_space(4.0);
let text_style = TextStyle::Body; let text_style = TextStyle::Body;
let row_height = ui.fonts().row_height(text_style) + ui.spacing().item_spacing.y; let row_height = ui.fonts().row_height(&text_style) + ui.spacing().item_spacing.y;
let num_rows = 10_000; let num_rows = 10_000;
ScrollArea::vertical() ScrollArea::vertical()
@ -130,7 +130,7 @@ fn huge_content_painter(ui: &mut egui::Ui) {
pos2(x, y), pos2(x, y),
Align2::LEFT_TOP, Align2::LEFT_TOP,
text, text,
text_style, text_style.clone(),
ui.visuals().text_color(), ui.visuals().text_color(),
); );
used_rect = used_rect.union(text_rect); used_rect = used_rect.union(text_rect);
@ -265,7 +265,7 @@ impl super::View for ScrollStickTo {
ui.add_space(4.0); ui.add_space(4.0);
let text_style = TextStyle::Body; let text_style = TextStyle::Body;
let row_height = ui.fonts().row_height(text_style); let row_height = ui.fonts().row_height(&text_style);
ScrollArea::vertical().stick_to_bottom().show_rows( ScrollArea::vertical().stick_to_bottom().show_rows(
ui, ui,
row_height, row_height,

View file

@ -18,7 +18,7 @@ pub fn easy_mark_it<'em>(ui: &mut Ui, items: impl Iterator<Item = easy_mark::Ite
ui.allocate_ui_with_layout(initial_size, layout, |ui| { ui.allocate_ui_with_layout(initial_size, layout, |ui| {
ui.spacing_mut().item_spacing.x = 0.0; ui.spacing_mut().item_spacing.x = 0.0;
let row_height = ui.fonts().row_height(TextStyle::Body); let row_height = ui.fonts().row_height(&TextStyle::Body);
ui.set_row_height(row_height); ui.set_row_height(row_height);
for item in items { for item in items {
@ -28,7 +28,7 @@ pub fn easy_mark_it<'em>(ui: &mut Ui, items: impl Iterator<Item = easy_mark::Ite
} }
pub fn item_ui(ui: &mut Ui, item: easy_mark::Item<'_>) { pub fn item_ui(ui: &mut Ui, item: easy_mark::Item<'_>) {
let row_height = ui.fonts().row_height(TextStyle::Body); let row_height = ui.fonts().row_height(&TextStyle::Body);
let one_indent = row_height / 2.0; let one_indent = row_height / 2.0;
match item { match item {
@ -134,7 +134,7 @@ fn rich_text_from_style(text: &str, style: &easy_mark::Style) -> RichText {
} }
fn bullet_point(ui: &mut Ui, width: f32) -> Response { fn bullet_point(ui: &mut Ui, width: f32) -> Response {
let row_height = ui.fonts().row_height(TextStyle::Body); let row_height = ui.fonts().row_height(&TextStyle::Body);
let (rect, response) = ui.allocate_exact_size(vec2(width, row_height), Sense::hover()); let (rect, response) = ui.allocate_exact_size(vec2(width, row_height), Sense::hover());
ui.painter().circle_filled( ui.painter().circle_filled(
rect.center(), rect.center(),
@ -145,7 +145,7 @@ fn bullet_point(ui: &mut Ui, width: f32) -> Response {
} }
fn numbered_point(ui: &mut Ui, width: f32, number: &str) -> Response { fn numbered_point(ui: &mut Ui, width: f32, number: &str) -> Response {
let row_height = ui.fonts().row_height(TextStyle::Body); let row_height = ui.fonts().row_height(&TextStyle::Body);
let (rect, response) = ui.allocate_exact_size(vec2(width, row_height), Sense::hover()); let (rect, response) = ui.allocate_exact_size(vec2(width, row_height), Sense::hover());
let text = format!("{}.", number); let text = format!("{}.", number);
let text_color = ui.visuals().strong_text_color(); let text_color = ui.visuals().strong_text_color();

View file

@ -116,7 +116,7 @@ impl SyntectTheme {
} }
} }
#[derive(Clone, Copy, Hash, PartialEq)] #[derive(Clone, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))] #[cfg_attr(feature = "serde", serde(default))]
pub struct CodeTheme { pub struct CodeTheme {
@ -158,15 +158,15 @@ impl CodeTheme {
} }
} }
pub fn store_in_memory(&self, ctx: &egui::Context) { pub fn store_in_memory(self, ctx: &egui::Context) {
if self.dark_mode { if self.dark_mode {
ctx.memory() ctx.memory()
.data .data
.insert_persisted(egui::Id::new("dark"), *self); .insert_persisted(egui::Id::new("dark"), self);
} else { } else {
ctx.memory() ctx.memory()
.data .data
.insert_persisted(egui::Id::new("light"), *self); .insert_persisted(egui::Id::new("light"), self);
} }
} }
} }
@ -206,12 +206,12 @@ impl CodeTheme {
Self { Self {
dark_mode: true, dark_mode: true,
formats: enum_map::enum_map![ formats: enum_map::enum_map![
TokenType::Comment => TextFormat::simple(text_style, Color32::from_gray(120)), TokenType::Comment => TextFormat::simple(text_style.clone(), Color32::from_gray(120)),
TokenType::Keyword => TextFormat::simple(text_style, Color32::from_rgb(255, 100, 100)), TokenType::Keyword => TextFormat::simple(text_style.clone(), Color32::from_rgb(255, 100, 100)),
TokenType::Literal => TextFormat::simple(text_style, Color32::from_rgb(87, 165, 171)), TokenType::Literal => TextFormat::simple(text_style.clone(), Color32::from_rgb(87, 165, 171)),
TokenType::StringLiteral => TextFormat::simple(text_style, Color32::from_rgb(109, 147, 226)), TokenType::StringLiteral => TextFormat::simple(text_style.clone(), Color32::from_rgb(109, 147, 226)),
TokenType::Punctuation => TextFormat::simple(text_style, Color32::LIGHT_GRAY), TokenType::Punctuation => TextFormat::simple(text_style.clone(), Color32::LIGHT_GRAY),
TokenType::Whitespace => TextFormat::simple(text_style, Color32::TRANSPARENT), TokenType::Whitespace => TextFormat::simple(text_style.clone(), Color32::TRANSPARENT),
], ],
} }
} }
@ -223,12 +223,12 @@ impl CodeTheme {
dark_mode: false, dark_mode: false,
#[cfg(not(feature = "syntect"))] #[cfg(not(feature = "syntect"))]
formats: enum_map::enum_map![ formats: enum_map::enum_map![
TokenType::Comment => TextFormat::simple(text_style, Color32::GRAY), TokenType::Comment => TextFormat::simple(text_style.clone(), Color32::GRAY),
TokenType::Keyword => TextFormat::simple(text_style, Color32::from_rgb(235, 0, 0)), TokenType::Keyword => TextFormat::simple(text_style.clone(), Color32::from_rgb(235, 0, 0)),
TokenType::Literal => TextFormat::simple(text_style, Color32::from_rgb(153, 134, 255)), TokenType::Literal => TextFormat::simple(text_style.clone(), Color32::from_rgb(153, 134, 255)),
TokenType::StringLiteral => TextFormat::simple(text_style, Color32::from_rgb(37, 203, 105)), TokenType::StringLiteral => TextFormat::simple(text_style.clone(), Color32::from_rgb(37, 203, 105)),
TokenType::Punctuation => TextFormat::simple(text_style, Color32::DARK_GRAY), TokenType::Punctuation => TextFormat::simple(text_style.clone(), Color32::DARK_GRAY),
TokenType::Whitespace => TextFormat::simple(text_style, Color32::TRANSPARENT), TokenType::Whitespace => TextFormat::simple(text_style.clone(), Color32::TRANSPARENT),
], ],
} }
} }
@ -259,7 +259,7 @@ impl CodeTheme {
// (TokenType::Whitespace, "whitespace"), // (TokenType::Whitespace, "whitespace"),
] { ] {
let format = &mut self.formats[tt]; let format = &mut self.formats[tt];
ui.style_mut().override_text_style = Some(format.style); ui.style_mut().override_text_style = Some(format.style.clone());
ui.visuals_mut().override_text_color = Some(format.color); ui.visuals_mut().override_text_color = Some(format.color);
ui.radio_value(&mut selected_tt, tt, tt_name); ui.radio_value(&mut selected_tt, tt, tt_name);
} }
@ -412,7 +412,7 @@ impl Highligher {
while !text.is_empty() { while !text.is_empty() {
if text.starts_with("//") { if text.starts_with("//") {
let end = text.find('\n').unwrap_or_else(|| text.len()); let end = text.find('\n').unwrap_or_else(|| text.len());
job.append(&text[..end], 0.0, theme.formats[TokenType::Comment]); job.append(&text[..end], 0.0, theme.formats[TokenType::Comment].clone());
text = &text[end..]; text = &text[end..];
} else if text.starts_with('"') { } else if text.starts_with('"') {
let end = text[1..] let end = text[1..]
@ -420,7 +420,11 @@ impl Highligher {
.map(|i| i + 2) .map(|i| i + 2)
.or_else(|| text.find('\n')) .or_else(|| text.find('\n'))
.unwrap_or_else(|| text.len()); .unwrap_or_else(|| text.len());
job.append(&text[..end], 0.0, theme.formats[TokenType::StringLiteral]); job.append(
&text[..end],
0.0,
theme.formats[TokenType::StringLiteral].clone(),
);
text = &text[end..]; text = &text[end..];
} else if text.starts_with(|c: char| c.is_ascii_alphanumeric()) { } else if text.starts_with(|c: char| c.is_ascii_alphanumeric()) {
let end = text[1..] let end = text[1..]
@ -432,19 +436,27 @@ impl Highligher {
} else { } else {
TokenType::Literal TokenType::Literal
}; };
job.append(word, 0.0, theme.formats[tt]); job.append(word, 0.0, theme.formats[tt].clone());
text = &text[end..]; text = &text[end..];
} else if text.starts_with(|c: char| c.is_ascii_whitespace()) { } else if text.starts_with(|c: char| c.is_ascii_whitespace()) {
let end = text[1..] let end = text[1..]
.find(|c: char| !c.is_ascii_whitespace()) .find(|c: char| !c.is_ascii_whitespace())
.map_or_else(|| text.len(), |i| i + 1); .map_or_else(|| text.len(), |i| i + 1);
job.append(&text[..end], 0.0, theme.formats[TokenType::Whitespace]); job.append(
&text[..end],
0.0,
theme.formats[TokenType::Whitespace].clone(),
);
text = &text[end..]; text = &text[end..];
} else { } else {
let mut it = text.char_indices(); let mut it = text.char_indices();
it.next(); it.next();
let end = it.next().map_or(text.len(), |(idx, _chr)| idx); let end = it.next().map_or(text.len(), |(idx, _chr)| idx);
job.append(&text[..end], 0.0, theme.formats[TokenType::Punctuation]); job.append(
&text[..end],
0.0,
theme.formats[TokenType::Punctuation].clone(),
);
text = &text[end..]; text = &text[end..];
} }
} }

View file

@ -270,8 +270,8 @@ impl Font {
} }
#[inline(always)] #[inline(always)]
pub fn text_style(&self) -> TextStyle { pub fn text_style(&self) -> &TextStyle {
self.text_style &self.text_style
} }
#[inline(always)] #[inline(always)]

View file

@ -11,7 +11,7 @@ use crate::{
// TODO: rename // TODO: rename
/// One of a few categories of styles of text, e.g. body, button or heading. /// One of a few categories of styles of text, e.g. body, button or heading.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum TextStyle { pub enum TextStyle {
@ -37,7 +37,7 @@ impl TextStyle {
TextStyle::Monospace, TextStyle::Monospace,
] ]
.iter() .iter()
.copied() .cloned()
} }
} }
@ -270,13 +270,13 @@ impl Fonts {
/// Width of this character in points. /// Width of this character in points.
#[inline] #[inline]
pub fn glyph_width(&self, text_style: TextStyle, c: char) -> f32 { pub fn glyph_width(&self, text_style: &TextStyle, c: char) -> f32 {
self.lock().fonts.glyph_width(text_style, c) self.lock().fonts.glyph_width(text_style, c)
} }
/// Height of one row of text. In points /// Height of one row of text. In points
#[inline] #[inline]
pub fn row_height(&self, text_style: TextStyle) -> f32 { pub fn row_height(&self, text_style: &TextStyle) -> f32 {
self.lock().fonts.row_height(text_style) self.lock().fonts.row_height(text_style)
} }
@ -398,17 +398,17 @@ impl FontsImpl {
let fonts = definitions let fonts = definitions
.family_and_size .family_and_size
.iter() .iter()
.map(|(&text_style, &(family, scale_in_points))| { .map(|(text_style, (family, scale_in_points))| {
let fonts = &definitions.fonts_for_family.get(&family); let fonts = &definitions.fonts_for_family.get(family);
let fonts = fonts.unwrap_or_else(|| { let fonts = fonts.unwrap_or_else(|| {
panic!("FontFamily::{:?} is not bound to any fonts", family) panic!("FontFamily::{:?} is not bound to any fonts", family)
}); });
let fonts: Vec<Arc<FontImpl>> = fonts let fonts: Vec<Arc<FontImpl>> = fonts
.iter() .iter()
.map(|font_name| font_impl_cache.font_impl(font_name, scale_in_points)) .map(|font_name| font_impl_cache.font_impl(font_name, *scale_in_points))
.collect(); .collect();
(text_style, Font::new(text_style, fonts)) (text_style.clone(), Font::new(text_style.clone(), fonts))
}) })
.collect(); .collect();
@ -430,18 +430,18 @@ impl FontsImpl {
} }
#[inline] #[inline]
pub fn font_mut(&mut self, text_style: TextStyle) -> &mut Font { pub fn font_mut(&mut self, text_style: &TextStyle) -> &mut Font {
self.fonts.get_mut(&text_style).unwrap() self.fonts.get_mut(text_style).unwrap()
} }
/// Width of this character in points. /// Width of this character in points.
fn glyph_width(&mut self, text_style: TextStyle, c: char) -> f32 { fn glyph_width(&mut self, text_style: &TextStyle, c: char) -> f32 {
self.font_mut(text_style).glyph_width(c) self.font_mut(text_style).glyph_width(c)
} }
/// Height of one row of text. In points /// Height of one row of text. In points
fn row_height(&self, text_style: TextStyle) -> f32 { fn row_height(&mut self, text_style: &TextStyle) -> f32 {
self.fonts[&text_style].row_height() self.font_mut(text_style).row_height()
} }
} }

View file

@ -86,7 +86,7 @@ fn layout_section(
byte_range, byte_range,
format, format,
} = section; } = section;
let font = fonts.font_mut(format.style); let font = fonts.font_mut(&format.style);
let font_height = font.row_height(); let font_height = font.row_height();
let mut paragraph = out_paragraphs.last_mut().unwrap(); let mut paragraph = out_paragraphs.last_mut().unwrap();

View file

@ -156,7 +156,7 @@ impl LayoutJob {
pub fn font_height(&self, fonts: &crate::Fonts) -> f32 { pub fn font_height(&self, fonts: &crate::Fonts) -> f32 {
let mut max_height = 0.0_f32; let mut max_height = 0.0_f32;
for section in &self.sections { for section in &self.sections {
max_height = max_height.max(fonts.row_height(section.format.style)); max_height = max_height.max(fonts.row_height(&section.format.style));
} }
max_height max_height
} }
@ -213,7 +213,7 @@ impl std::hash::Hash for LayoutSection {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#[derive(Copy, Clone, Debug, Hash, PartialEq)] #[derive(Clone, Debug, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TextFormat { pub struct TextFormat {
pub style: TextStyle, pub style: TextStyle,