fix(render): environment-aware atlas drift guard, pinned text scale, shipped-atlas coverage

This commit is contained in:
Martino Ferrari committed 2026-09-28 10:54:00 +02:00
1 parent 5ca3587325
commit 1cb5970757
6 files changed
+257 -31

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include <plot/core/types.hpp>
namespace plot::render::detail {
/// The factor a text run is drawn by: `requested_px / em_px`, a plain ratio.
///
/// It is a ratio rather than a whole multiple because the renderer's built-in
/// face is anti-aliased: a style asking for 12 px from a 13 px bake is drawn at
/// 12/13, where a 1-bit glyph would have had to snap to the nearest multiple of
/// its cell. Everything the renderer stages is scaled by this one factor, so the
/// labels a plot laid out and the glyphs the pipeline draws cannot disagree.
///
/// A backend that cannot state an em -- `em_px()` at or below zero, or NaN --
/// yields a 1:1 scale rather than dividing by it or propagating a NaN into every
/// vertex. The requested size being NaN, zero or negative does the same. The rule
/// lives here, not inline in the renderer, so it is one function and can be
/// asserted without a GL context; it is instrumentation-free and part of no
/// public surface (`*/detail/` headers stay out of the umbrella).
inline f32 text_scale(f32 requested_px, f32 em_px) noexcept {
const f32 ratio = requested_px / em_px;
return (em_px > 0.0f && ratio > 0.0f) ? ratio : 1.0f;
}
} // namespace plot::render::detail
+5 -3
View File
@@ -115,9 +115,11 @@ class TextBackend {
/// backend was baked at: the renderer scales by `requested_px / em_px()`, so a
/// backend re-baked at another size -- or swapped for a different face -- keeps
/// drawing `Style::axis_font_px`, and the renderer never has to know which font
/// it holds. A backend with no meaningful em (one whose "font pixels" are an
/// arbitrary unit) returns something proportional, `height()` being the
/// natural choice.
///
/// A backend that *wraps* another to draw it at a size scales this with the
/// rest of its metrics -- it is in the wrapper's units, like `height()` -- so a
/// caller that reads the backend back and draws at `requested_px / em_px()`
/// gets a ratio of two screen-pixel quantities and cannot scale twice.
virtual f32 em_px() const = 0;
/// The glyph for `codepoint`, or null when this backend has none -- the caller