Open abey79 opened 2 months ago
There are three alternatives:
pixels_per_point
is an integerI'd like to understand a bit more what the trade-offs are between these.
Regardless of how/if we round widgets during layout, we still want to round some visual shapes to physical pixels to make them crisper (text, thin lines, etc).
Since we need to round some visual shapes to physical pixels anyway, always rounding to physical pixels may produce more even results.
All calculations are done in logical ui points, and so if we make them integers we prevent rounding errors.
Unaligned cursor lead to various visual glitches.
I'd like a repro for this
I'd like a repro for this
use eframe::egui;
fn main() -> eframe::Result {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]),
..Default::default()
};
eframe::run_native(
"My egui App",
options,
Box::new(|cc| {
// This gives us image support:
egui_extras::install_image_loaders(&cc.egui_ctx);
Ok(Box::new(MyApp))
}),
)
}
struct MyApp;
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
// unaligned cursor
ui.add_space(0.1234);
ui.spacing_mut().item_spacing.y = 0.0;
for _ in 0..5 {
let (rect, _) =
ui.allocate_exact_size(egui::vec2(100.0, 20.0), egui::Sense::hover());
ui.painter()
.rect_filled(rect, 0.0, ui.style().visuals.selection.bg_fill);
}
});
}
}
Commenting out the mis-alignment line gives the expect result:
One notch of zooming-in (cmd-+) brings back the glitch though:
There are three alternatives:
- Round widgets to physical pixels
- Round widgets to logical ui points
- Only round when
pixels_per_point
is an integer- No rounding
In light of the repro above, I believe rounding to physical pixels is what's needed, but, ultimately, whatever fixes this 😅
The problem there is the feathering (anti-aliasing) of the boxes.
The easy fix there would be to always align boxes to the pixel grid, and turn of feathering for them. The usefulness of feathering on axis-aligned boxes is minimal anyway. If you're animating boxes then it will make them move smoother, but that seems quite niche.
Related:
I think the correct thing to do here is to align ui points to integers in order to avoid rounding errors in width calculations and similar (see e.g. https://github.com/emilk/egui/issues/5084).
The problem of rendering rectangles side-by-side without a seem is a purely visual one, and can be solved separately by one of these means:
RectShape
I've opened two new issues for this:
Unaligned cursor lead to various visual glitches. It would be nice to have an API to "fix" the cursor position. This would avoid using code like this:
which is not robust to layout orientation and assumes 1:1 physical pixels.
Related: