07a9b35208
- Introduced `theme.rs` to handle visual themes, font discovery, and application of theme colors. - Implemented system font registration for Linux, macOS, and Windows. - Added `apply_theme` function to configure egui visuals based on selected theme presets. feat: Implement interactive tool state management - Created `tool_state.rs` to manage runtime tool, selection, and transform states. - Defined `ToolState` struct to encapsulate active tool, color settings, drawing states, and AI panel states. - Included functionality for managing brush presets, text editing, and selection transformations. feat: Add utility functions for image and file handling - Developed `utils.rs` with stateless helper functions for color formatting, drawing icons, and cropping images. - Implemented save dialog builders and error handling for file operations. - Added flood fill functionality for composite RGBA pixels. test: Add unit test for bitmap brush stamp functionality - Created `bitmap_brush_stamp.rs` to verify the behavior of bitmap brush stamping in the engine. - Ensured that the painted area matches expected dimensions and characteristics.
50 lines
1.8 KiB
Rust
50 lines
1.8 KiB
Rust
use hcie_engine_api::{Engine, BrushTip, BrushStyle};
|
|
|
|
#[test]
|
|
fn bitmap_brush_stamp_shape() {
|
|
let mut engine = Engine::new(64, 64);
|
|
// 4x4 solid white square bitmap stamp
|
|
let mut pixels = vec![0u8; 16];
|
|
for i in 0..16 { pixels[i] = 255; }
|
|
let brush = BrushTip {
|
|
style: BrushStyle::Bitmap,
|
|
size: 8.0,
|
|
opacity: 1.0,
|
|
hardness: 1.0,
|
|
spacing: 1.0,
|
|
bitmap_pixels: pixels,
|
|
bitmap_w: 4,
|
|
bitmap_h: 4,
|
|
..Default::default()
|
|
};
|
|
engine.set_brush_tip(brush);
|
|
engine.begin_stroke(engine.active_layer_id(), 20.0, 20.0);
|
|
engine.stroke_to(engine.active_layer_id(), 20.0, 20.0, 1.0);
|
|
engine.end_stroke(engine.active_layer_id());
|
|
let output = engine.get_composite_pixels();
|
|
|
|
// Check that the painted area is roughly 4x4, not a circular blob.
|
|
// Count alpha > 0 pixels and bounding box.
|
|
let mut min_x = 63; let mut max_x = 0; let mut min_y = 63; let mut max_y = 0;
|
|
let mut count = 0;
|
|
for y in 0..64 {
|
|
for x in 0..64 {
|
|
let a = output[(y*64+x)*4+3];
|
|
if a > 0 {
|
|
count += 1;
|
|
if x < min_x { min_x = x; }
|
|
if x > max_x { max_x = x; }
|
|
if y < min_y { min_y = y; }
|
|
if y > max_y { max_y = y; }
|
|
}
|
|
}
|
|
}
|
|
let w = (max_x - min_x + 1) as i32;
|
|
let h = (max_y - min_y + 1) as i32;
|
|
// Should fit inside ~8x8 because size=8 and stamp 4x4 scaled up
|
|
assert!(w <= 8 && h <= 8, "bitmap dab bounding box {}x{} too large for 4x4 stamp", w, h);
|
|
assert!(count >= 8, "bitmap dab should paint some pixels");
|
|
// Square-ish: aspect ratio not too far from 1 (was very low for circle vs square?)
|
|
assert!(w.abs_diff(h) <= 2, "bitmap dab bounding box should be roughly square, got {}x{}", w, h);
|
|
}
|