-
|
Hi! How can I determine a monospaced font's effective char-to-char "stride" (char width + char spacing) at the current zoom level, so that I can do the usual layout (indentation, for example) and pointer-pos-to-char-cell mapping? I've read trough the online docs for various For reference, I hacked up this worky but inefficient and inelegant code and found that the Thanks! let text_style = egui::TextStyle::Monospace;
let text_format = TextFormat {
color: ui.visuals().override_text_color.unwrap_or(Color32::BLACK),
font_id: text_style.resolve(ui.style()),
..TextFormat::default()
};
if self.prev_zoom_factor != ui.ctx().zoom_factor() { // Lay out some text to determine the char_stride; I can't find a way to determine the inter-character spacing for a monospace font in egui
self.prev_zoom_factor = ui.ctx().zoom_factor();
ui.ctx().fonts(|fonts| {
let mut job = LayoutJob::default();
job.append("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 0.0, text_format.clone());
let galley = fonts.layout_job(job);
let glyphs = &galley.rows.first().unwrap().glyphs;
self.char_stride = (glyphs.last().unwrap().pos.x - glyphs.first().unwrap().pos.x) / (glyphs.len() - 1) as f32;
println!("{}", self.char_stride);
});
} |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
|
https://docs.rs/egui/latest/egui/text/struct.Fonts.html#method.glyph_width and https://docs.rs/egui/latest/egui/text/struct.Fonts.html#method.row_height may be close to what you want. |
Beta Was this translation helpful? Give feedback.
-
|
https://docs.rs/egui/latest/egui/struct.Galley.html#method.cursor_from_pos may also be useful if this is a bit of an XY problem since you mentioned you want to map from pointer pos to char cell. |
Beta Was this translation helpful? Give feedback.
-
|
Ok, thanks to your answer, I dug in a bit more. What happens in the galley layout code is that each character is aligned to a pixel so that it renders clearly, so the actual achieved spacing (what I call the So, the floating point I still don't understand how the zoom factor interacts with this, but I don't need to. The Thanks again for cluebatting me, it made me dig in deeper.
P.S. Here's the code in egui that does the rounding ( paragraph.cursor_x = font.round_to_pixel(paragraph.cursor_x); |
Beta Was this translation helpful? Give feedback.
Ok, thanks to your answer, I dug in a bit more.
What happens in the galley layout code is that each character is aligned to a pixel so that it renders clearly, so the actual achieved spacing (what I call the
stride) is, on average, a bit off, and ends up being an integer.So, the floating point
glyph.advance_width(what the font metrics you linked to yields, many thanks!!!) is the ideal advance width; the slight rounding off of each glyph'spos.xcauses the actual advance width to be an integer. Here, at the moment,glyph.advance_widthis8.639999, and the "stride" measured by the above code is9.000000. Using thestrideworks perfectly for char cell <-> cursor X mapping So, I'll keep the…