Size a panorama's cell and thumbnail by class: two, three or four columns

One lookup, natural_span, maps a photograph's aspect to the columns its
cell spans, and the same number names its thumbnail class, Wide2, Wide3
or Wide4, 512 pixels of long edge per column, so a 4:1 panorama is as
sharp across four columns as a frame is in one. The boundaries are
where the two neighbouring cells would leave the same share of
themselves undrawn, sqrt(s(s+1)): 2.45 and 3.46, with the first at 1.9
so a 3:2 frame stays a frame. A grid too narrow for the class falls
back to the widest that fits, the tablet gives the whole row, and a
cell asks for the class it is actually drawn at: its span, but never
more than its own class. The merge renders each wide class up to the
composite's own, which covers every fallback.
This commit is contained in:
2026-09-28 19:57:37 -04:00
parent ae4e1a0f07
commit 6050a8e703
5 changed files with 155 additions and 56 deletions
+14 -8
View File
@@ -116,14 +116,14 @@ impl Reduced {
}
/// Which size classes a composite of this shape is thumbnailed at: the two
/// every photograph has, and the wide one where the grid will give it a
/// wide cell.
/// every photograph has, and the wide classes its cell can be drawn at —
/// its own, from the one lookup the grid packs by, and each narrower one a
/// grid with too few columns falls back to.
pub fn classes(width: u32, height: u32) -> Vec<ThumbSize> {
let aspect = width as f32 / height.max(1) as f32;
let natural = crate::library_ui::layout::natural_span(Some(aspect));
let mut out = vec![ThumbSize::Grid, ThumbSize::Large];
if crate::library_ui::layout::natural_span(Some(aspect)) > 1 {
out.push(ThumbSize::Wide);
}
out.extend((2..=natural).filter_map(ThumbSize::wide));
out
}
@@ -198,8 +198,14 @@ mod tests {
#[test]
fn a_panorama_is_thumbnailed_for_its_wide_cell_and_a_squat_merge_is_not() {
assert_eq!(classes(22_000, 5_600).last(), Some(&ThumbSize::Wide));
assert!(!classes(9_000, 6_000).contains(&ThumbSize::Wide));
use ThumbSize::*;
assert_eq!(
classes(22_000, 5_600),
[Grid, Large, Wide2, Wide3, Wide4],
"a 3.9:1 panorama spans four"
);
assert_eq!(classes(8_000, 4_000), [Grid, Large, Wide2]);
assert_eq!(classes(9_000, 6_000), [Grid, Large]);
}
#[test]
@@ -359,7 +365,7 @@ mod tests {
&header,
Some(crop),
decoder,
&[ThumbSize::Grid, ThumbSize::Large, ThumbSize::Wide],
&classes(crop.width, crop.height),
)
.unwrap();