When using a custom font you can now specify a font index (#873)

When using a custom font you can now specify a font index

Closes https://github.com/emilk/egui/issues/853
This commit is contained in:
Emil Ernerfeldt 2021-11-07 19:47:52 +01:00 committed by GitHub
parent 10c8ffa543
commit 878eddd546
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 17 deletions

View file

@ -11,6 +11,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* Add context menus: See `Ui::menu_button` and `Response::context_menu` ([#543](https://github.com/emilk/egui/pull/543)). * Add context menus: See `Ui::menu_button` and `Response::context_menu` ([#543](https://github.com/emilk/egui/pull/543)).
* You can now read and write the cursor of a `TextEdit` ([#848](https://github.com/emilk/egui/pull/848)). * You can now read and write the cursor of a `TextEdit` ([#848](https://github.com/emilk/egui/pull/848)).
* Most widgets containing text (`Label`, `Button` etc) now supports rich text ([#855](https://github.com/emilk/egui/pull/855)). * Most widgets containing text (`Label`, `Button` etc) now supports rich text ([#855](https://github.com/emilk/egui/pull/855)).
* When using a custom font you can now specify a font index ([#873](https://github.com/emilk/egui/pull/873)).
### Changed 🔧 ### Changed 🔧
* Unifiy the four `Memory` data buckets (`data`, `data_temp`, `id_data` and `id_data_temp`) into a single `Memory::data`, with a new interface ([#836](https://github.com/emilk/egui/pull/836)). * Unifiy the four `Memory` data buckets (`data`, `data_temp`, `id_data` and `id_data_temp`) into a single `Memory::data`, with a new interface ([#836](https://github.com/emilk/egui/pull/836)).

View file

@ -385,12 +385,15 @@ pub use epaint::emath;
pub use emath::{lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rect, Vec2}; pub use emath::{lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rect, Vec2};
pub use epaint::{ pub use epaint::{
color, mutex, color, mutex,
text::{FontDefinitions, FontFamily, TextStyle}, text::{FontData, FontDefinitions, FontFamily, TextStyle},
ClippedMesh, Color32, Rgba, Shape, Stroke, Texture, TextureId, ClippedMesh, Color32, Rgba, Shape, Stroke, Texture, TextureId,
}; };
pub mod text { pub mod text {
pub use epaint::text::{Fonts, Galley, LayoutJob, LayoutSection, TextFormat, TAB_SIZE}; pub use epaint::text::{
FontData, FontDefinitions, FontFamily, Fonts, Galley, LayoutJob, LayoutSection, TextFormat,
TextStyle, TAB_SIZE,
};
} }
pub use { pub use {

View file

@ -52,13 +52,43 @@ pub enum FontFamily {
Proportional, Proportional,
} }
/// The data of a `.ttf` or `.otf` file. /// A `.ttf` or `.otf` file and a font face index.
pub type FontData = std::borrow::Cow<'static, [u8]>; #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct FontData {
/// The data of a `.ttf` or `.otf` file.
pub font: std::borrow::Cow<'static, [u8]>,
/// Which font face in the file to use.
/// When in doubt, use `0`.
pub index: u32,
}
impl FontData {
pub fn from_static(font: &'static [u8]) -> Self {
Self {
font: std::borrow::Cow::Borrowed(font),
index: 0,
}
}
pub fn from_owned(font: Vec<u8>) -> Self {
Self {
font: std::borrow::Cow::Owned(font),
index: 0,
}
}
}
fn ab_glyph_font_from_font_data(name: &str, data: &FontData) -> ab_glyph::FontArc { fn ab_glyph_font_from_font_data(name: &str, data: &FontData) -> ab_glyph::FontArc {
match data { match &data.font {
std::borrow::Cow::Borrowed(bytes) => ab_glyph::FontArc::try_from_slice(bytes), std::borrow::Cow::Borrowed(bytes) => {
std::borrow::Cow::Owned(bytes) => ab_glyph::FontArc::try_from_vec(bytes.clone()), ab_glyph::FontRef::try_from_slice_and_index(bytes, data.index)
.map(ab_glyph::FontArc::from)
}
std::borrow::Cow::Owned(bytes) => {
ab_glyph::FontVec::try_from_vec_and_index(bytes.clone(), data.index)
.map(ab_glyph::FontArc::from)
}
} }
.unwrap_or_else(|err| panic!("Error parsing {:?} TTF/OTF font file: {}", name, err)) .unwrap_or_else(|err| panic!("Error parsing {:?} TTF/OTF font file: {}", name, err))
} }
@ -85,7 +115,7 @@ fn ab_glyph_font_from_font_data(name: &str, data: &FontData) -> ab_glyph::FontAr
/// ///
/// You can also install your own custom fonts: /// You can also install your own custom fonts:
/// ``` /// ```
/// # use {epaint::text::{FontDefinitions, TextStyle, FontFamily}}; /// # use {epaint::text::{FontDefinitions, TextStyle, FontFamily, FontData}};
/// # struct FakeEguiCtx {}; /// # struct FakeEguiCtx {};
/// # impl FakeEguiCtx { fn set_fonts(&self, _: FontDefinitions) {} } /// # impl FakeEguiCtx { fn set_fonts(&self, _: FontDefinitions) {} }
/// # let ctx = FakeEguiCtx {}; /// # let ctx = FakeEguiCtx {};
@ -93,7 +123,7 @@ fn ab_glyph_font_from_font_data(name: &str, data: &FontData) -> ab_glyph::FontAr
/// ///
/// // Install my own font (maybe supporting non-latin characters): /// // Install my own font (maybe supporting non-latin characters):
/// fonts.font_data.insert("my_font".to_owned(), /// fonts.font_data.insert("my_font".to_owned(),
/// std::borrow::Cow::Borrowed(include_bytes!("../../fonts/Ubuntu-Light.ttf"))); // .ttf and .otf supported /// FontData::from_static(include_bytes!("../../fonts/Ubuntu-Light.ttf"))); // .ttf and .otf supported
/// ///
/// // Put my font first (highest priority): /// // Put my font first (highest priority):
/// fonts.fonts_for_family.get_mut(&FontFamily::Proportional).unwrap() /// fonts.fonts_for_family.get_mut(&FontFamily::Proportional).unwrap()
@ -110,10 +140,8 @@ fn ab_glyph_font_from_font_data(name: &str, data: &FontData) -> ab_glyph::FontAr
#[cfg_attr(feature = "serde", serde(default))] #[cfg_attr(feature = "serde", serde(default))]
pub struct FontDefinitions { pub struct FontDefinitions {
/// List of font names and their definitions. /// List of font names and their definitions.
/// The definition must be the contents of either a `.ttf` or `.otf` font file.
/// ///
/// `epaint` has built-in-default for these, /// `epaint` has built-in-default for these, but you can override them if you like.
/// but you can override them if you like.
pub font_data: BTreeMap<String, FontData>, pub font_data: BTreeMap<String, FontData>,
/// Which fonts (names) to use for each [`FontFamily`]. /// Which fonts (names) to use for each [`FontFamily`].
@ -139,22 +167,22 @@ impl Default for FontDefinitions {
{ {
font_data.insert( font_data.insert(
"Hack".to_owned(), "Hack".to_owned(),
std::borrow::Cow::Borrowed(include_bytes!("../../fonts/Hack-Regular.ttf")), FontData::from_static(include_bytes!("../../fonts/Hack-Regular.ttf")),
); );
font_data.insert( font_data.insert(
"Ubuntu-Light".to_owned(), "Ubuntu-Light".to_owned(),
std::borrow::Cow::Borrowed(include_bytes!("../../fonts/Ubuntu-Light.ttf")), FontData::from_static(include_bytes!("../../fonts/Ubuntu-Light.ttf")),
); );
// Some good looking emojis. Use as first priority: // Some good looking emojis. Use as first priority:
font_data.insert( font_data.insert(
"NotoEmoji-Regular".to_owned(), "NotoEmoji-Regular".to_owned(),
std::borrow::Cow::Borrowed(include_bytes!("../../fonts/NotoEmoji-Regular.ttf")), FontData::from_static(include_bytes!("../../fonts/NotoEmoji-Regular.ttf")),
); );
// Bigger emojis, and more. <http://jslegers.github.io/emoji-icon-font/>: // Bigger emojis, and more. <http://jslegers.github.io/emoji-icon-font/>:
font_data.insert( font_data.insert(
"emoji-icon-font".to_owned(), "emoji-icon-font".to_owned(),
std::borrow::Cow::Borrowed(include_bytes!("../../fonts/emoji-icon-font.ttf")), FontData::from_static(include_bytes!("../../fonts/emoji-icon-font.ttf")),
); );
fonts_for_family.insert( fonts_for_family.insert(

View file

@ -10,7 +10,7 @@ mod text_layout_types;
pub const TAB_SIZE: usize = 4; pub const TAB_SIZE: usize = 4;
pub use { pub use {
fonts::{FontDefinitions, FontFamily, Fonts, TextStyle}, fonts::{FontData, FontDefinitions, FontFamily, Fonts, TextStyle},
text_layout::layout, text_layout::layout,
text_layout_types::*, text_layout_types::*,
}; };