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:
@@ -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..];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user