Text warps: bands with fewer lines keep the fuller band's text height
Multi-band fill warps (Deflate-Inflate, Button Pour) map a box as tall as the tallest band's ink onto every band, centred on the band's own ink, as PowerPoint does: a band holding one line next to a band of two keeps the line at the same size instead of stretching it over the whole band. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fe5ecc1b85
commit
6521789c2c
|
|
@ -4,7 +4,8 @@
|
||||||
//! Text lines are shared out over the bands in order (the first ⌈n/k⌉ lines to the first band
|
//! Text lines are shared out over the bands in order (the first ⌈n/k⌉ lines to the first band
|
||||||
//! and so on). A band either
|
//! and so on). A band either
|
||||||
//! - stretches its lines between a top and a bottom guide ([`Band::Fill`]): the ink box of the
|
//! - stretches its lines between a top and a bottom guide ([`Band::Fill`]): the ink box of the
|
||||||
//! band's lines fills the band vertically, and horizontally the text is scaled so that the
|
//! band's lines fills the band vertically (a band whose ink is shorter than the tallest band's
|
||||||
|
//! keeps the same scale, centred), and horizontally the text is scaled so that the
|
||||||
//! widest band is filled along the mean length of its guides (one scale for the whole text), or
|
//! widest band is filled along the mean length of its guides (one scale for the whole text), or
|
||||||
//! - sets its lines at their natural size along one guide ([`Band::Follow`], arches and circles):
|
//! - sets its lines at their natural size along one guide ([`Band::Follow`], arches and circles):
|
||||||
//! glyphs keep their size, are placed by arc length (aligned as in the paragraph, the whole
|
//! glyphs keep their size, are placed by arc length (aligned as in the paragraph, the whole
|
||||||
|
|
@ -658,6 +659,11 @@ impl Warp {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Every fill band maps a box as tall as the tallest band's ink, centred on its own ink, so
|
||||||
|
// a band with fewer lines keeps them at the same size, centred between its guides.
|
||||||
|
let tallest = band_y.iter().flatten().map(|(y0, y1)| y1 - y0).fold(0.0, f64::max);
|
||||||
|
let band_y: Vec<Option<(f64, f64)>> =
|
||||||
|
band_y.iter().map(|r| r.map(|(y0, y1)| ((y0 + y1 - tallest) / 2.0, (y0 + y1 + tallest) / 2.0))).collect();
|
||||||
for (b, band) in self.bands.iter().enumerate() {
|
for (b, band) in self.bands.iter().enumerate() {
|
||||||
if let Band::Fill { top, bottom } = band {
|
if let Band::Fill { top, bottom } = band {
|
||||||
let half = lines
|
let half = lines
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,15 @@ fn deflate_inflate_maps_each_band_separately() {
|
||||||
assert!((m.map(0, Point::new(100.0, 40.0)).y / H - 0.45).abs() < 0.004);
|
assert!((m.map(0, Point::new(100.0, 40.0)).y / H - 0.45).abs() < 0.004);
|
||||||
assert!((m.map(1, Point::new(100.0, 50.0)).y / H - 0.55).abs() < 0.004);
|
assert!((m.map(1, Point::new(100.0, 50.0)).y / H - 0.55).abs() < 0.004);
|
||||||
assert!((m.map(1, Point::new(300.0, 80.0)).y / H - 1.0).abs() < 0.004);
|
assert!((m.map(1, Point::new(300.0, 80.0)).y / H - 1.0).abs() < 0.004);
|
||||||
|
// A band with fewer lines keeps them at the size of the fuller band, centred in its band:
|
||||||
|
// two lines (ink 10..60) in band 1, one line (ink 70..80) in band 2 of three.
|
||||||
|
let a = WarpLine { ink: Some(Rect::new(100.0, 10.0, 300.0, 30.0)), extent: (100.0, 300.0), ref_y: 28.0 };
|
||||||
|
let b = WarpLine { ink: Some(Rect::new(100.0, 40.0, 300.0, 60.0)), extent: (100.0, 300.0), ref_y: 58.0 };
|
||||||
|
let c = WarpLine { ink: Some(Rect::new(100.0, 70.0, 300.0, 80.0)), extent: (100.0, 300.0), ref_y: 78.0 };
|
||||||
|
let m = w.mapper(&[a, b, c], rect());
|
||||||
|
let (top, bot) = (m.map(2, Point::new(200.0, 70.0)).y / H, m.map(2, Point::new(200.0, 80.0)).y / H);
|
||||||
|
// Band 2 runs from 0.4 to 1 at the centre; the line takes the middle fifth of it.
|
||||||
|
assert!((top - 0.64).abs() < 0.005 && (bot - 0.76).abs() < 0.005, "{top} {bot}");
|
||||||
// A shorter first line keeps its share of the width.
|
// A shorter first line keeps its share of the width.
|
||||||
let short = WarpLine { ink: Some(Rect::new(150.0, 10.0, 250.0, 40.0)), extent: (150.0, 250.0), ref_y: 34.0 };
|
let short = WarpLine { ink: Some(Rect::new(150.0, 10.0, 250.0, 40.0)), extent: (150.0, 250.0), ref_y: 34.0 };
|
||||||
let m = w.mapper(&[short, l2], rect());
|
let m = w.mapper(&[short, l2], rect());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue