1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 06:10:06 -04:00

Choose your own font and size (#1154)

* Refactor text layout: don't need &Fonts in all functions
* Replace indexing in Fonts with member function
* Wrap Fonts in a Mutex
* Remove mutex for Font::glyph_info_cache
* Remove RwLock around Font::characters
* Put FontsImpl and GalleyCache behind the same Mutex
* Round font sizes to whole pixels before deduplicating them
* Make TextStyle !Copy
* Implement user-named TextStyle:s
* round font size earlier
* Cache fonts based on family and size
* Move TextStyle into egui and Style
* Remove body_text_style
* Query graphics about max texture size and use that as font atlas size
* Recreate texture atlas when it is getting full
This commit is contained in:
Emil Ernerfeldt
2022-01-24 14:32:36 +01:00
committed by GitHub
parent bb407e9b00
commit fa43d16c41
67 changed files with 1231 additions and 640 deletions

View File

@@ -13,7 +13,7 @@ pub fn code_view_ui(ui: &mut egui::Ui, mut code: &str) {
ui.add(
egui::TextEdit::multiline(&mut code)
.text_style(egui::TextStyle::Monospace) // for cursor height
.font(egui::TextStyle::Monospace) // for cursor height
.code_editor()
.desired_rows(1)
.lock_focus(true)
@@ -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", serde(default))]
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 {
ctx.memory()
.data
.insert_persisted(egui::Id::new("dark"), *self);
.insert_persisted(egui::Id::new("dark"), self);
} else {
ctx.memory()
.data
.insert_persisted(egui::Id::new("light"), *self);
.insert_persisted(egui::Id::new("light"), self);
}
}
}
@@ -201,34 +201,34 @@ impl CodeTheme {
#[cfg(not(feature = "syntect"))]
impl CodeTheme {
pub fn dark() -> Self {
let text_style = egui::TextStyle::Monospace;
let font_id = egui::FontId::monospace(12.0);
use egui::{Color32, TextFormat};
Self {
dark_mode: true,
formats: enum_map::enum_map![
TokenType::Comment => TextFormat::simple(text_style, Color32::from_gray(120)),
TokenType::Keyword => TextFormat::simple(text_style, Color32::from_rgb(255, 100, 100)),
TokenType::Literal => TextFormat::simple(text_style, Color32::from_rgb(87, 165, 171)),
TokenType::StringLiteral => TextFormat::simple(text_style, Color32::from_rgb(109, 147, 226)),
TokenType::Punctuation => TextFormat::simple(text_style, Color32::LIGHT_GRAY),
TokenType::Whitespace => TextFormat::simple(text_style, Color32::TRANSPARENT),
TokenType::Comment => TextFormat::simple(font_id.clone(), Color32::from_gray(120)),
TokenType::Keyword => TextFormat::simple(font_id.clone(), Color32::from_rgb(255, 100, 100)),
TokenType::Literal => TextFormat::simple(font_id.clone(), Color32::from_rgb(87, 165, 171)),
TokenType::StringLiteral => TextFormat::simple(font_id.clone(), Color32::from_rgb(109, 147, 226)),
TokenType::Punctuation => TextFormat::simple(font_id.clone(), Color32::LIGHT_GRAY),
TokenType::Whitespace => TextFormat::simple(font_id.clone(), Color32::TRANSPARENT),
],
}
}
pub fn light() -> Self {
let text_style = egui::TextStyle::Monospace;
let font_id = egui::FontId::monospace(12.0);
use egui::{Color32, TextFormat};
Self {
dark_mode: false,
#[cfg(not(feature = "syntect"))]
formats: enum_map::enum_map![
TokenType::Comment => TextFormat::simple(text_style, Color32::GRAY),
TokenType::Keyword => TextFormat::simple(text_style, Color32::from_rgb(235, 0, 0)),
TokenType::Literal => TextFormat::simple(text_style, Color32::from_rgb(153, 134, 255)),
TokenType::StringLiteral => TextFormat::simple(text_style, Color32::from_rgb(37, 203, 105)),
TokenType::Punctuation => TextFormat::simple(text_style, Color32::DARK_GRAY),
TokenType::Whitespace => TextFormat::simple(text_style, Color32::TRANSPARENT),
TokenType::Comment => TextFormat::simple(font_id.clone(), Color32::GRAY),
TokenType::Keyword => TextFormat::simple(font_id.clone(), Color32::from_rgb(235, 0, 0)),
TokenType::Literal => TextFormat::simple(font_id.clone(), Color32::from_rgb(153, 134, 255)),
TokenType::StringLiteral => TextFormat::simple(font_id.clone(), Color32::from_rgb(37, 203, 105)),
TokenType::Punctuation => TextFormat::simple(font_id.clone(), Color32::DARK_GRAY),
TokenType::Whitespace => TextFormat::simple(font_id.clone(), Color32::TRANSPARENT),
],
}
}
@@ -259,7 +259,7 @@ impl CodeTheme {
// (TokenType::Whitespace, "whitespace"),
] {
let format = &mut self.formats[tt];
ui.style_mut().override_text_style = Some(format.style);
ui.style_mut().override_font_id = Some(format.font_id.clone());
ui.visuals_mut().override_text_color = Some(format.color);
ui.radio_value(&mut selected_tt, tt, tt_name);
}
@@ -325,7 +325,7 @@ impl Highligher {
// Fallback:
LayoutJob::simple(
code.into(),
egui::TextStyle::Monospace,
egui::FontId::monospace(14.0),
if theme.dark_mode {
egui::Color32::LIGHT_GRAY
} else {
@@ -371,7 +371,7 @@ impl Highligher {
leading_space: 0.0,
byte_range: as_byte_range(text, range),
format: TextFormat {
style: egui::TextStyle::Monospace,
font_id: egui::FontId::monospace(14.0),
color: text_color,
italics,
underline,
@@ -412,7 +412,7 @@ impl Highligher {
while !text.is_empty() {
if text.starts_with("//") {
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..];
} else if text.starts_with('"') {
let end = text[1..]
@@ -420,7 +420,11 @@ impl Highligher {
.map(|i| i + 2)
.or_else(|| text.find('\n'))
.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..];
} else if text.starts_with(|c: char| c.is_ascii_alphanumeric()) {
let end = text[1..]
@@ -432,19 +436,27 @@ impl Highligher {
} else {
TokenType::Literal
};
job.append(word, 0.0, theme.formats[tt]);
job.append(word, 0.0, theme.formats[tt].clone());
text = &text[end..];
} else if text.starts_with(|c: char| c.is_ascii_whitespace()) {
let end = text[1..]
.find(|c: char| !c.is_ascii_whitespace())
.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..];
} else {
let mut it = text.char_indices();
it.next();
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..];
}
}