// The settled screen, computed from the keyframe times alone. // // `rest()` picks each element's last HOLD keyframe independently, which is right // for an element that ends settled and wrong for a transient: a 2-frame flash // holds at its PEAK, so `rest()` leaves it burning forever. The settled screen is // instead one INSTANT that every element is posed at, and the instant to pick is // inside the longest interval during which no element has a keyframe at all. use sylpheed_formats::{pak, ui_layout}; fn main(){ let mut a=std::env::args().skip(1); let pk=a.next().unwrap(); let ar=pak::PakArchive::open(&pk).unwrap(); let only:Option=a.next().and_then(|s|s.parse().ok()); for (i,e) in ar.entries().iter().enumerate() { if let Some(o)=only { if o!=i { continue } } let Ok(by)=ar.read(e) else { continue }; let Some(b)=ui_layout::parse_build(&by) else { continue }; if b.elements.len()<2 { continue } let mut ts:Vec=b.elements.iter().flat_map(|el| el.keyframes.iter().filter_map(|k|k.time)).collect(); if ts.len()<2 { continue } ts.sort_unstable(); ts.dedup(); // longest gap between consecutive keyframe times let (mut best,mut lo,mut hi)=(0u32,0u32,0u32); for w in ts.windows(2) { if w[1]-w[0] > best { best=w[1]-w[0]; lo=w[0]; hi=w[1]; } } println!("{:>4} {:<28} times {:>3} span {:>4} settle window [{lo},{hi}] = {best} units ({:.2}s) -> t={}", i, format!("{:08x}",e.name_hash), ts.len(), ts.last().unwrap(), best as f64/60.0, lo+best/2); } }