mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 22:00:03 -04:00
Make the width of the thin space configurable (#8070)
Adds `FontTweak::thin_space_width` and `FontTweak::tab_size`
This commit is contained in:
@@ -458,8 +458,8 @@ pub use epaint::{
|
|||||||
pub mod text {
|
pub mod text {
|
||||||
pub use crate::text_selection::CCursorRange;
|
pub use crate::text_selection::CCursorRange;
|
||||||
pub use epaint::text::{
|
pub use epaint::text::{
|
||||||
FontData, FontDefinitions, FontFamily, Fonts, Galley, LayoutJob, LayoutSection, TAB_SIZE,
|
FontData, FontDefinitions, FontFamily, Fonts, Galley, LayoutJob, LayoutSection, TextFormat,
|
||||||
TextFormat, TextWrapping, cursor::CCursor,
|
TextWrapping, cursor::CCursor,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2915,6 +2915,8 @@ impl Widget for &mut FontTweak {
|
|||||||
y_offset,
|
y_offset,
|
||||||
hinting_override,
|
hinting_override,
|
||||||
coords,
|
coords,
|
||||||
|
thin_space_width,
|
||||||
|
tab_size,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui.label("Scale");
|
ui.label("Scale");
|
||||||
@@ -2987,6 +2989,21 @@ impl Widget for &mut FontTweak {
|
|||||||
}
|
}
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.label("thin_space_width");
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.add(
|
||||||
|
DragValue::new(thin_space_width)
|
||||||
|
.range(0.0..=1.0)
|
||||||
|
.speed(0.01),
|
||||||
|
);
|
||||||
|
ui.label("1\u{2009}234\u{2009}567\u{2009}890");
|
||||||
|
});
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.label("tab_size");
|
||||||
|
ui.add(DragValue::new(tab_size).range(0.0..=16.0).speed(0.1));
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
if ui.button("Reset").clicked() {
|
if ui.button("Reset").clicked() {
|
||||||
*self = Default::default();
|
*self = Default::default();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use std::{borrow::Cow, ops::Range};
|
use std::{borrow::Cow, ops::Range};
|
||||||
|
|
||||||
use epaint::{
|
use epaint::{Galley, text::cursor::CCursor};
|
||||||
Galley,
|
|
||||||
text::{TAB_SIZE, cursor::CCursor},
|
/// One `\t` character is this many spaces wide (for indentation purposes).
|
||||||
};
|
const TAB_SIZE: usize = 4;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
text::CCursorRange,
|
text::CCursorRange,
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:2ef07080ca2aa10e128c646479b8b322a092d63f15b35c52ed59015e7c2a0f60
|
oid sha256:6d64cc7d014cf063689a4dd8a6cdd87eb944f9637890baf32f59a258342400bf
|
||||||
size 15434
|
size 15400
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4edb61c6619d5e44892fa29da0aa0a624306ae637dbbaa057e3fa47c14dc06bd
|
oid sha256:9e9f800546cc98bbd92f31072aceef10b5b8b9bbef0db4c8f4dbae652aefec61
|
||||||
size 35988
|
size 35918
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f8da0c2e37497968864a91fa6bef7c545c37791f4f9b788ea9a2f43dd4ac16b1
|
oid sha256:e3f6e1cc6a069ac96ff9e039ce85462453ee943b4cb46080550bc1c0749ad658
|
||||||
size 16116
|
size 16085
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:2a603fcb2eb97943d6be3239b91cacee093adcb55a6dd14af93a72fc8b3a61fa
|
oid sha256:5901b5a8201b85b51118193eef300749a4569eedc62043cd4e03f76e73a12f51
|
||||||
size 39270
|
size 39222
|
||||||
|
|||||||
@@ -432,8 +432,7 @@ impl FontFace {
|
|||||||
&& let Some(space) = self.glyph_info(' ')
|
&& let Some(space) = self.glyph_info(' ')
|
||||||
{
|
{
|
||||||
let glyph_info = GlyphInfo {
|
let glyph_info = GlyphInfo {
|
||||||
advance_width_unscaled: (crate::text::TAB_SIZE as f32
|
advance_width_unscaled: (self.tweak.tab_size * space.advance_width_unscaled.0)
|
||||||
* space.advance_width_unscaled.0)
|
|
||||||
.into(),
|
.into(),
|
||||||
..space
|
..space
|
||||||
};
|
};
|
||||||
@@ -441,21 +440,18 @@ impl FontFace {
|
|||||||
return Some(glyph_info);
|
return Some(glyph_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if c == '\u{2009}' {
|
if (c == '\u{2009}' || c == '\u{202F}')
|
||||||
// Thin space, often used as thousands deliminator: 1 234 567 890
|
&& let Some(space) = self.glyph_info(' ')
|
||||||
// https://www.compart.com/en/unicode/U+2009
|
{
|
||||||
// https://en.wikipedia.org/wiki/Thin_space
|
// Thin space (U+2009) and narrow no-break space (U+202F),
|
||||||
|
// often used as thousands separator: 1 234 567 890
|
||||||
if let Some(space) = self.glyph_info(' ') {
|
let advance_width = self.tweak.thin_space_width * space.advance_width_unscaled.0;
|
||||||
let em = self.font.borrow_dependent().metrics.units_per_em as f32;
|
let glyph_info = GlyphInfo {
|
||||||
let advance_width = f32::min(em / 6.0, space.advance_width_unscaled.0 * 0.5); // TODO(emilk): make configurable
|
advance_width_unscaled: advance_width.into(),
|
||||||
let glyph_info = GlyphInfo {
|
..space
|
||||||
advance_width_unscaled: advance_width.into(),
|
};
|
||||||
..space
|
self.glyph_info_cache.insert(c, glyph_info);
|
||||||
};
|
return Some(glyph_info);
|
||||||
self.glyph_info_cache.insert(c, glyph_info);
|
|
||||||
return Some(glyph_info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if invisible_char(c) {
|
if invisible_char(c) {
|
||||||
|
|||||||
@@ -193,6 +193,19 @@ pub struct FontTweak {
|
|||||||
|
|
||||||
/// Override the font's default variation coordinates.
|
/// Override the font's default variation coordinates.
|
||||||
pub coords: VariationCoords,
|
pub coords: VariationCoords,
|
||||||
|
|
||||||
|
/// Width of a thin space (`\u{2009}`) and narrow no-break space (`\u{202F}`),
|
||||||
|
/// as a fraction of the normal space width.
|
||||||
|
///
|
||||||
|
/// Thin space is often used as a thousands separator: `1 234 567`.
|
||||||
|
///
|
||||||
|
/// Default: `0.5` (half a normal space).
|
||||||
|
pub thin_space_width: f32,
|
||||||
|
|
||||||
|
/// Width of a tab character (`\t`), measured in number of space widths.
|
||||||
|
///
|
||||||
|
/// Default: `4.0`.
|
||||||
|
pub tab_size: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FontTweak {
|
impl Default for FontTweak {
|
||||||
@@ -203,6 +216,8 @@ impl Default for FontTweak {
|
|||||||
y_offset: 0.0,
|
y_offset: 0.0,
|
||||||
hinting_override: None,
|
hinting_override: None,
|
||||||
coords: VariationCoords::default(),
|
coords: VariationCoords::default(),
|
||||||
|
thin_space_width: 0.5,
|
||||||
|
tab_size: 4.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ mod fonts;
|
|||||||
mod text_layout;
|
mod text_layout;
|
||||||
mod text_layout_types;
|
mod text_layout_types;
|
||||||
|
|
||||||
/// One `\t` character is this many spaces wide.
|
|
||||||
pub const TAB_SIZE: usize = 4;
|
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
fonts::{
|
fonts::{
|
||||||
FontData, FontDefinitions, FontFamily, FontId, FontInsert, FontPriority, FontTweak, Fonts,
|
FontData, FontDefinitions, FontFamily, FontId, FontInsert, FontPriority, FontTweak, Fonts,
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use crate::{
|
|||||||
Color32, Mesh, Stroke, Vertex,
|
Color32, Mesh, Stroke, Vertex,
|
||||||
stroke::PathStroke,
|
stroke::PathStroke,
|
||||||
text::{
|
text::{
|
||||||
TAB_SIZE,
|
|
||||||
font::{StyledMetrics, UvRect, is_cjk, is_cjk_break_allowed},
|
font::{StyledMetrics, UvRect, is_cjk, is_cjk_break_allowed},
|
||||||
fonts::FontFaceKey,
|
fonts::FontFaceKey,
|
||||||
},
|
},
|
||||||
@@ -250,11 +249,23 @@ fn layout_shaped_run(
|
|||||||
.unwrap_or('\u{FFFD}'); // Unicode Replacement Character
|
.unwrap_or('\u{FFFD}'); // Unicode Replacement Character
|
||||||
|
|
||||||
// Tab is a layout concept, not a glyph — the shaper doesn't know about tab stops.
|
// Tab is a layout concept, not a glyph — the shaper doesn't know about tab stops.
|
||||||
// Override the advance width to TAB_SIZE × space width.
|
// Override the advance width using the font's configured tab size.
|
||||||
if chr == '\t' {
|
if chr == '\t' {
|
||||||
|
let tweak = font.fonts_by_id.get(&run.font_key).map(|ff| ff.tweak());
|
||||||
|
let tab_size = tweak.map_or(4.0, |t| t.tab_size);
|
||||||
let (_, space_info) = font.glyph_info(' ');
|
let (_, space_info) = font.glyph_info(' ');
|
||||||
let space_width_px = space_info.advance_width_unscaled.0 * px_scale;
|
let space_width_px = space_info.advance_width_unscaled.0 * px_scale;
|
||||||
advance_width_px = TAB_SIZE as f32 * space_width_px;
|
advance_width_px = tab_size * space_width_px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thin space (U+2009) and narrow no-break space (U+202F):
|
||||||
|
// override the shaper's advance width with the configured fraction of a space.
|
||||||
|
if chr == '\u{2009}' || chr == '\u{202F}' {
|
||||||
|
let tweak = font.fonts_by_id.get(&run.font_key).map(|ff| ff.tweak());
|
||||||
|
let thin_space_width = tweak.map_or(0.5, |t| t.thin_space_width);
|
||||||
|
let (_, space_info) = font.glyph_info(' ');
|
||||||
|
let space_width_px = space_info.advance_width_unscaled.0 * px_scale;
|
||||||
|
advance_width_px = thin_space_width * space_width_px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply extra_letter_spacing only at cluster boundaries,
|
// Apply extra_letter_spacing only at cluster boundaries,
|
||||||
|
|||||||
Reference in New Issue
Block a user