feat(render): logical style metrics with a UI scale, so chrome has a consistent physical size

This commit is contained in:
Martino Ferrari committed 2026-09-28 12:17:53 +02:00
1 parent 1f03631e98
commit 7500fc90d2
21 files changed
+708 -82

No files matched your search

+37
View File
@@ -452,3 +452,40 @@ PLOT_TEST(imgui_widget_paints_only_the_visible_part_of_a_clipped_child) {
f.pixel(f.paint_min_x + 40u, f.paint_min_y + 40u, out);
PLOT_CHECK(!f.is_host(out));
}
/// The widget states the display's scale to the renderer, which is what makes the
/// chrome one physical size on any DPI: `io.DisplayFramebufferScale` is the same
/// factor the widget already maps points to framebuffer pixels by, so a host on a 2x
/// surface gets a 2x *device* font and a 2x device strip -- the same logical layout
/// as on a 1x one.
PLOT_TEST(imgui_widget_states_the_display_scale_to_the_renderer) {
Fixture f;
PLOT_CHECK(f.init());
ImGuiIO& io = ImGui::GetIO();
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
f.frame(ImVec2(10.0f, 10.0f), false);
PLOT_CHECK_NEAR(f.renderer.style().ui_scale, 1.0f, 1e-6);
const plot::f32 cell_1x = f.renderer.axis_font_px();
const plot::f32 strip_1x = f.plot.layout().y_axis_width;
PLOT_CHECK(cell_1x > 1.0f);
PLOT_CHECK(strip_1x > 1.0f);
// The same widget and the same logical size, on a 2x surface.
io.DisplayFramebufferScale = ImVec2(2.0f, 2.0f);
f.frame(ImVec2(10.0f, 10.0f), false);
PLOT_CHECK_NEAR(f.renderer.style().ui_scale, 2.0f, 1e-6);
// The renderer hands it to the plot before laying out, so the *device* chrome
// doubles while the logical figure (device / scale) is what the 1x run measured.
PLOT_CHECK_NEAR(f.plot.ui_scale(), 2.0f, 1e-6);
PLOT_CHECK_NEAR(f.renderer.axis_font_px(), 2.0f * cell_1x, 1e-3);
PLOT_CHECK_NEAR(f.plot.layout().y_axis_width, 2.0f * strip_1x, 0.05f);
// Back to 1x: the scale is re-read every frame rather than latched at the first
// one, so a window moved to another display follows.
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
f.frame(ImVec2(10.0f, 10.0f), false);
PLOT_CHECK_NEAR(f.renderer.style().ui_scale, 1.0f, 1e-6);
PLOT_CHECK_NEAR(f.renderer.axis_font_px(), cell_1x, 1e-3);
PLOT_CHECK_NEAR(f.plot.layout().y_axis_width, strip_1x, 1e-3);
}