diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d16fcc55d9..005d2ed584d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)). * 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)). +* When using a custom font you can now specify a font index ([#873](https://github.com/emilk/egui/pull/873)). ### 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)). diff --git a/egui/src/lib.rs b/egui/src/lib.rs index 6e3bd01ca53..36dffbc1286 100644 --- a/egui/src/lib.rs +++ b/egui/src/lib.rs @@ -391,12 +391,15 @@ pub use emath as math; // historical reasons pub use emath::{lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rect, Vec2}; pub use epaint::{ color, mutex, - text::{FontDefinitions, FontFamily, TextStyle}, + text::{FontData, FontDefinitions, FontFamily, TextStyle}, ClippedMesh, Color32, Rgba, Shape, Stroke, Texture, TextureId, }; 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 { diff --git a/epaint/src/text/fonts.rs b/epaint/src/text/fonts.rs index cd242ba24b7..8fb6d9f03ae 100644 --- a/epaint/src/text/fonts.rs +++ b/epaint/src/text/fonts.rs @@ -52,13 +52,43 @@ pub enum FontFamily { Proportional, } -/// The data of a `.ttf` or `.otf` file. -pub type FontData = std::borrow::Cow<'static, [u8]>; +/// A `.ttf` or `.otf` file and a font face index. +#[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) -> Self { + Self { + font: std::borrow::Cow::Owned(font), + index: 0, + } + } +} fn ab_glyph_font_from_font_data(name: &str, data: &FontData) -> ab_glyph::FontArc { - match data { - std::borrow::Cow::Borrowed(bytes) => ab_glyph::FontArc::try_from_slice(bytes), - std::borrow::Cow::Owned(bytes) => ab_glyph::FontArc::try_from_vec(bytes.clone()), + match &data.font { + std::borrow::Cow::Borrowed(bytes) => { + 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)) } @@ -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: /// ``` -/// # use {epaint::text::{FontDefinitions, TextStyle, FontFamily}}; +/// # use {epaint::text::{FontDefinitions, TextStyle, FontFamily, FontData}}; /// # struct FakeEguiCtx {}; /// # impl FakeEguiCtx { fn set_fonts(&self, _: FontDefinitions) {} } /// # 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): /// 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): /// 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))] pub struct FontDefinitions { /// 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, - /// but you can override them if you like. + /// `epaint` has built-in-default for these, but you can override them if you like. pub font_data: BTreeMap, /// Which fonts (names) to use for each [`FontFamily`]. @@ -139,22 +167,22 @@ impl Default for FontDefinitions { { font_data.insert( "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( "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: font_data.insert( "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. : font_data.insert( "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( diff --git a/epaint/src/text/mod.rs b/epaint/src/text/mod.rs index 34897b72555..ee2b5c07b8b 100644 --- a/epaint/src/text/mod.rs +++ b/epaint/src/text/mod.rs @@ -10,7 +10,7 @@ mod text_layout_types; pub const TAB_SIZE: usize = 4; pub use { - fonts::{FontDefinitions, FontFamily, Fonts, TextStyle}, + fonts::{FontData, FontDefinitions, FontFamily, Fonts, TextStyle}, text_layout::layout, text_layout_types::*, };