Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions crates/engine/src/cmd/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1701,11 +1701,14 @@ fn publication(s: &mut Session, p: &Value) -> CmdResult {
let (ix, iy, iw, ih) = (r.0 + pad, r.1 + pad, lw - 2.0 * pad, lh - 2.0 * pad);
let bar_fit = if bar.is_some() { bar_h.min(ih) } else { 0.0 };
let rows_h = (ih - bar_fit - if bar.is_some() { bar_part - bar_h } else { 0.0 }).max(0.0);
if ch > 0.0 && (cw > iw || ch > rows_h) {
// A box sized to its content, less the padding again, can come out a rounding error
// short of it: that still fits.
const FIT_MM: f64 = 1e-6;
if ch > 0.0 && (cw > iw + FIT_MM || ch > rows_h + FIT_MM) {
warnings.push("the legend lists more than fits its corner: its last rows or the ends of long labels are left out".into());
}
// In a column the colorbar takes the column's width, as its rows do.
if bar.is_some() && ((bar_w > iw && !legend_in_column) || bar_h > ih) {
if bar.is_some() && ((bar_w > iw + FIT_MM && !legend_in_column) || bar_h > ih + FIT_MM) {
warnings.push("the legend's box is smaller than the colorbar: it is drawn narrower or shorter".into());
}
if ch > 0.0 && rows_h >= 1.0 {
Expand Down
23 changes: 23 additions & 0 deletions crates/engine/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3183,6 +3183,29 @@ fn publication_surrounds_keep_off_the_data() {
let _ = std::fs::remove_dir_all(&dir);
}

/// A publication legend sized to its rows fits them: its box, less the padding, may come out a
/// rounding error short of the rows' width, which isn't "more than fits" (macOS CI, whose fonts
/// gave one such width). Layer names of many widths, so some land on a rounding error with any font.
#[test]
fn a_publication_legend_sized_to_its_rows_fits_them() {
let dir = std::env::temp_dir().join(format!("rustgis-legend-fit-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let names: Vec<String> = (0..300).map(|i| format!("{}{i}", &"WmilQxkaRb"[i % 10..])).collect();
for name in &names {
let path = dir.join(format!("{name}.geojson"));
std::fs::write(
&path,
r#"{"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": [[[4,4],[6,4],[6,6],[4,6],[4,4]]]}}]}"#,
)
.unwrap();
let mut s = Session::new(Project::default());
s.run("layer.addData", &json!({"path": path.display().to_string()})).unwrap();
let r = s.run("layout.publication", &json!({"extent": [0, 0, 10, 10], "author": ""})).unwrap();
assert!(!r["warnings"].to_string().contains("more than fits"), "{name}: {r}");
}
let _ = std::fs::remove_dir_all(&dir);
}

/// A publication layout keys a raster theme with a colorbar: the topmost visible raster drawn on a
/// ramp gets one at the bottom of the legend's box; a map of vectors only gets none.
#[test]
Expand Down
Loading