Files
hcie-rust-v3.05/hcie-engine-api-orig/tests/visibility_bug.rs
T
2026-07-09 02:59:53 +03:00

105 lines
4.4 KiB
Rust

use hcie_engine_api::Engine;
fn count_opaque_pixels(pixels: &[u8]) -> usize {
pixels.iter().skip(3).step_by(4).filter(|&&a| a > 0).count()
}
fn has_non_black_pixel(pixels: &[u8]) -> bool {
pixels.chunks_exact(4).any(|px| px[0] > 0 || px[1] > 0 || px[2] > 0 || px[3] > 0)
}
#[test]
fn test_visibility_toggle_bug_repro() {
let mut engine = Engine::new(100, 100);
// Fill background layer (layer 0) with opaque white
let bg_id = engine.active_layer_id();
engine.draw_filled_rect_rgba(0, 0, 100, 100, [255, 255, 255, 255]);
log::info!("=== AFTER FILL BG: pixels should be white ===");
let p = engine.get_composite_pixels();
log::info!(" composite opaque pixels: {}/{}", count_opaque_pixels(&p), 100*100);
assert_eq!(count_opaque_pixels(&p), 100*100, "background should be fully opaque");
// Add a new layer on top
let top_id = engine.add_layer("Top Layer");
log::info!("=== AFTER ADD TOP LAYER: id={} ===", top_id);
let p = engine.get_composite_pixels();
log::info!(" composite opaque pixels: {}/{} (expected 10000)", count_opaque_pixels(&p), 100*100);
// After adding layer, composite should still show the background (10000 opaque)
// Draw something on the top layer
engine.draw_filled_rect_rgba(20, 20, 80, 80, [0, 0, 0, 255]);
log::info!("=== AFTER DRAW ON TOP: black square 60x60 at (20,20) ===");
let p = engine.get_composite_pixels();
log::info!(" composite opaque pixels: {}/{} (expected 10000)", count_opaque_pixels(&p), 100*100);
assert_eq!(count_opaque_pixels(&p), 100*100, "all pixels should still be opaque");
// Now hide the BACKGROUND layer
log::info!("=== HIDE BACKGROUND (id={}) ===", bg_id);
engine.set_layer_visible(bg_id, false);
let p = engine.get_composite_pixels();
log::info!(" composite opaque pixels: {}/{} (expected 3600 = 60*60 black square)", count_opaque_pixels(&p), 100*100);
log::info!(" has non-black: {}", has_non_black_pixel(&p));
// After hiding background, only the black square (3600 px) should be visible
assert!(count_opaque_pixels(&p) > 0, "at least the drawn square should be visible");
assert!(count_opaque_pixels(&p) <= 3600 + 100, "only drawn square should be visible, got {}", count_opaque_pixels(&p));
// Show background again
log::info!("=== SHOW BACKGROUND (id={}) ===", bg_id);
engine.set_layer_visible(bg_id, true);
let p = engine.get_composite_pixels();
log::info!(" composite opaque pixels: {}/{} (expected 10000)", count_opaque_pixels(&p), 100*100);
assert_eq!(count_opaque_pixels(&p), 100*100, "all pixels should be opaque again");
}
#[test]
fn test_visibility_toggle_with_stroke() {
let mut engine = Engine::new(100, 100);
let bg_id = engine.active_layer_id();
engine.draw_filled_rect_rgba(0, 0, 100, 100, [255, 255, 255, 255]);
let top_id = engine.add_layer("Top Layer");
// Hide background
log::info!("=== HIDE BG, THEN STROKE ON TOP ===");
engine.set_layer_visible(bg_id, false);
// Begin a stroke on the top layer
engine.begin_stroke(top_id, 50.0, 50.0);
engine.stroke_to(top_id, 55.0, 55.0, 1.0);
engine.stroke_to(top_id, 60.0, 60.0, 1.0);
engine.end_stroke(top_id);
let p = engine.get_composite_pixels();
let opaque = count_opaque_pixels(&p);
log::info!(" After stroke with bg hidden: opaque pixels: {}/{}", opaque, 100*100);
log::info!(" has non-black: {}", has_non_black_pixel(&p));
// The stroke should be visible
assert!(opaque > 0, "stroke should be visible even with bg hidden");
}
#[test]
fn test_visibility_toggle_during_stroke() {
let mut engine = Engine::new(100, 100);
let bg_id = engine.active_layer_id();
engine.draw_filled_rect_rgba(0, 0, 100, 100, [255, 255, 255, 255]);
let top_id = engine.add_layer("Top Layer");
// Begin a stroke on the top layer
log::info!("=== STROKE THEN HIDE BG DURING STROKE ===");
engine.begin_stroke(top_id, 50.0, 50.0);
engine.stroke_to(top_id, 55.0, 55.0, 1.0);
// Hide background mid-stroke
engine.set_layer_visible(bg_id, false);
engine.stroke_to(top_id, 60.0, 60.0, 1.0);
engine.stroke_to(top_id, 65.0, 65.0, 1.0);
engine.end_stroke(top_id);
let p = engine.get_composite_pixels();
let opaque = count_opaque_pixels(&p);
log::info!(" After stroke with bg hidden mid-stroke: opaque pixels: {}/{}", opaque, 100*100);
assert!(opaque > 0, "stroke should be visible even after hiding bg mid-stroke");
}