The human chose Option A: teach sylpheed-formats own renderer to draw rotation_deg so it and the port stay comparable and verify-screen keeps meaning someone is wrong. Three pieces, because rotation alone does nothing on the title. blit gains a rotated path that draws by inverse mapping over the rotated bounding box, turning about the pivot, whose absolute position is invariant under scale; zero rotation keeps the original forward-mapped path byte for byte so non-rotating screens cannot regress. compose draws a nested .rat leaf when the leaf carries geometry the parent does not, which is the sweeps case, but not as a blanket rule since a button s leaf duplicates its parent. And --at poses leaves at a keyframe time, because the sweeps hold off-screen at x=1521 so a resting composite omits them. A trap found the hard way: posing EVERYTHING at one global time is wrong, because a top-level group s final keyframes are its exit ramp and rest() deliberately stops before them. Posing the title at t=358 walked every parent into its exit and drove the disagreement from 10.92 to 61.74. So at poses leaves only. Controls: 0 and 360 degrees byte-identical to the unrotated path, 90 degrees swaps a 10x4 to 4x10, area conserved within 15 percent, centroid stays on the pivot. 116 lib tests pass, main_menu unchanged at 9.26. And the verification did not show what it was meant to, which is reported rather than buried: scanning the pose time against the title capture gives 10.73 to 11.17 against a 10.92 baseline -- flat, no minimum, best 1.7 percent. The whole-frame mean is dominated by the tone curve, and the renderer still does not draw ptlogo1/ptlogo2 at all, which is a far larger spatial gap than two translucent sweeps. So rotation is correct in isolation and no screen regressed, but whether it closes the port s 1.81 percent is not established here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
21 lines
921 B
Rust
21 lines
921 B
Rust
use sylpheed_formats::{pak, ui_layout};
|
|
fn main(){
|
|
let ar=pak::PakArchive::open(std::env::args().nth(1).unwrap()).unwrap();
|
|
let by=ar.read(&ar.entries()[4]).unwrap();
|
|
let b=ui_layout::parse_build(&by).unwrap();
|
|
for n in ["ptloop01.rat","ptloop02.rat"] {
|
|
let el=b.elements.iter().find(|e| e.name==n).unwrap();
|
|
println!("{n}: kind={:#x} animated={} rec={:?}", el.kind, el.animated,
|
|
b.records.get(n).map(|&(o,s)|(o,s)));
|
|
if let Some(&(o,s))=b.records.get(n) {
|
|
match ui_layout::parse_build(&by[o..o+s]) {
|
|
Some(lb)=>for le in &lb.elements {
|
|
println!(" leaf {:?} sprite={:?} in_sprites={}", le.name, le.sprite,
|
|
le.sprite.as_ref().map(|x| b.sprites.contains_key(x)).unwrap_or(false));
|
|
},
|
|
None=>println!(" leaf parse FAILED"),
|
|
}
|
|
}
|
|
}
|
|
}
|