fix: a gridded view budgets its margins inside the delivered cap #198
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/grid-gutters-inside-the-cap"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The evidence
Box QA feedback (claude-sonnet-5.5, 10/11 15:38): "The text sentence for each crop often disagreed with the stated zoom and box, so I had to work out the scale from the image."
The defect
A gridded view capped its art at the 2048px delivered edge, then added the grid's margin gutters on top — so the composite left the renderer at e.g. 2126px. The gateway's re-encode (
ImageEncoder, the same 2048MaxDimension) then shrank the whole picture on the wire, art included. The account's scale was computed from the pre-shrink art, so the text overstated the art the model measured — by ~3.8% on a 1800×2600 page, ~30px across an 800px window, against box rules judged in 5px of slack. Non-gridded views were never affected; the cleaning views already budget theirTileGapinsideMaxSide(this is the inspection renderer catching up).The fix
One rule —
GridMetrics— computes the type size and both gutters, and serves both masters that must not disagree:WithGriddraws the same gutters from the same rule instead of re-deriving them.The budget is taken at the cap (the largest type the art could carry, therefore the largest gutters), so whatever the art comes to, its margins fit inside the room left for them.
Behaviour change
The art of a gridded view at the cap is up to ~130px smaller on its longest side (the gutters' worth); its account states the smaller scale, and that scale now matches the art to the pixel. Two existing pins updated to the delivered scales (
0.96×and0.47×, where1×and0.5×were pinned).Tests
PageImageRendererTests— page view and crop at the cap: the composite never exceeds 2048, and the stated scale is the measured art's (art detected in the delivered PNG, majority-grey per row/column, so the pin reads the picture the model gets, not the renderer's arithmetic). Mutation-verified: with the budget disabled, both fail at 2126/2128px — the original defect.Summary
Summary
Coverage
Orihon.BlazorAdapter - 96.6%
Orihon.Domain - 100%
Orihon.Infrastructure - 98.3%
n
ration
n
one
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlankLines_4
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlockBreaks_1
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__SpaceRuns_3
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__Tags_2
Orihon.Kernel - 90.9%
Orihon.Server - 95.1%
Orihon.UseCases - 94.5%
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__BalloonWords_7
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__Capital_0
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__CoordinateWords_1
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__JustBefore_4
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__KindWords_5
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__OutlineWords_6
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__PositionalProse_2
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__SideOfTheBox_3
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! A budget and a drawing served by one rule, so they can never disagree — and pixel-reading pins that judge the delivered PNG instead of the renderer's arithmetic. This is my favourite kind of PR~ ♡ One defect, one rule, two masters, tests that read the picture the model actually gets.
Verdict: ✅ Looks good to me~
I checked the invariant that makes the two-call design safe: the budget is taken at the cap (
GridMetrics.For(2048, raw)) whileWithGridsizes its gutters on the art as it landed (GridMetrics.For(max(art), raw)). That's only sound because gutter size is monotone inlongest—LabelSizeis a clamped quotient,padscales with it,MeasureTextof the sameWidest(raw)string grows with the font, andBottom = ceil(type + 2·pad)likewise. Art ≤ cap ⇒ drawn gutters ≤ budgeted gutters ⇒art + gutters ≤ capon both axes (ArtLongestsubtractsmax(Right, Bottom), which bounds each side's composite conservatively). The short axis can't escape:Fitcaps the longest side and the short side is ≤ it. Airtight~And the sibling precedent holds: the cleaning views already budget
TileGapinsideMaxSide(ViewTiling.CapacityinRasterCleaningViews) — this is the inspection renderer catching up to the established pattern, not inventing a new one. The non-gridded paths are untouched (margins is null⇒ exactly the old ceiling and the oldFit), whichA_view_nobody_asked_to_magnify_reports_no_refusal(0.68×, grid off) still pins. ♪And I probed it. Twice, with real mutants:
Fitto the raw cap) →A_gridded_page_view_spends_its_margins_inside_the_delivered_capand the re-pinnedA_downscaled_page_view_reports_the_magnification_it_was_delivered_atboth fail; the other 48 pass.A_gridded_crop_spends_its_margins_inside_the_delivered_capand the re-pinnedA_window_at_the_size_cap_steps_its_numbers_up_a_whole_magnitude_to_clear_themboth fail; the other 48 pass.Two probes, two kills, zero survivors — each mutant caught by precisely the guards that claim to catch it. The PR's own "mutation-verified" claim is no boast. Fufu~ ♡
💡 Little ideas (non-blocking)~
WithGridcomputesMath.Max(art.Width, art.Height)twice on adjacent lines (metricsthenlongest). Computinglongestfirst and passing it toGridMetrics.For(longest, raw)says it once.CeilingForre-derivesDeliveredLongestEdge - Math.Max(Right, Bottom), which is exactlyArtLongest;(decimal)ArtLongest / windowLongestwould make the two masters share even their arithmetic. Pure tidiness either way.✅ What I liked~
GridMetricsis DRY as a design principle, not an afterthought — the budget and the drawing cannot drift apart because they share a single birthplace. The comments even explain why they must not disagree. ♡ArtHeight/ArtWidthwith majority-grey detection measure the delivered PNG — the pin judges what the model receives, not what the renderer believes. And the anti-aliasing rationale (a digit's edge passes through the page's own grey) shows the test author understood their own instrument.1× → 0.96×and0.5× → 0.47×updates state the delivered truth with the reasoning in place, not silently edited constants.asked > ceiling) stays consistent with the new, lower gridded ceiling.Merge it with a clear conscience~ ♪
Automated review by Jibril · 2026-10-11
CI: green for head SHA
7c6b26fc03· Mutation probes: 2 run, 0 survived (page-budget mutant and crop-ceiling mutant, each killed by its intended guards) · Local suite: skipped (CI green)