fix: 矩形框移动出界

This commit is contained in:
2026-03-06 15:39:57 +08:00
parent d694a69723
commit 6db8941b67
2 changed files with 46 additions and 11 deletions

View File

@@ -68,6 +68,10 @@ impl MSColor {
let b = n as u8;
Self { r, g, b, a: 0xff }
}
pub fn invert(&self) -> Self {
Self::new(255 - self.r, 255 - self.g, 255 - self.b, self.a)
}
}
#[derive(Clone, Copy, PartialEq)]
@@ -1375,18 +1379,42 @@ impl MSCanvas {
}
pub fn draw_rect_selection(&mut self, x: i32, y: i32, rect: &RectSelection) {
let w = rect.w.min(self.width - x);
let h = rect.h.min(self.height - y);
// 边界检查
if x >= self.width || y >= self.height {
return;
}
// 考虑矩形四边出界的情况
let w = (rect.w as i32).min(self.width - x).min(rect.w + x);
let h = (rect.h as i32).min(self.height - y).min(rect.h + y);
if w == 0 || h == 0 {
return;
}
let mut src_offset_x = 0usize;
let mut src_offset_y = 0usize;
if x < 0 {
src_offset_x = (-x) as usize;
}
if y < 0 {
src_offset_y = (-y) as usize;
}
let x = x.max(0) as usize;
let y = y.max(0) as usize;
let w = w as usize;
let h = h as usize;
let width = self.width as usize;
for dy in 0..h {
for dx in 0..w {
let src_idx = ((dy * rect.w + dx) * 4) as usize;
let dst_idx = (((y + dy) * self.width + x + dx) * 4) as usize;
let src_start = ((dy + src_offset_y) * rect.w as usize + src_offset_x) * 4;
let dst_start = ((y + dy) * width + x) * 4;
self.pixels[dst_idx] = rect.pixels[src_idx];
self.pixels[dst_idx + 1] = rect.pixels[src_idx + 1];
self.pixels[dst_idx + 2] = rect.pixels[src_idx + 2];
self.pixels[dst_idx + 3] = rect.pixels[src_idx + 3];
// 使用 unsafe 块进一步优化(如果确定索引安全)
unsafe {
let src_slice = &rect.pixels.get_unchecked(src_start..src_start + w * 4);
let dst_slice = self.pixels.get_unchecked_mut(dst_start..dst_start + w * 4);
dst_slice.copy_from_slice(src_slice);
}
}
}

View File

@@ -394,7 +394,7 @@ impl PaintApp {
.height(Length::Fixed(height as f32));
let canvas_area = mouse_area(image_widget)
.on_press(|pos| Message::MousePressed(pos)) // 占位,实际逻辑在 on_drag 或自定义
.on_press(|pos| Message::MousePressed(pos))
.on_release(|pos| Message::MouseReleased(pos))
.on_move(|pos| Message::MouseMoved(pos))
.on_double_click(|pos| Message::MouseDoubleClick(pos))
@@ -811,7 +811,10 @@ impl PaintApp {
self.control_state = ControlState::Two;
} else {
self.release_rect_selection();
self.control_state = ControlState::Zero;
self.is_drawing = true;
self.view_canvas.save_pixels();
self.begin_point = pos;
self.control_state = ControlState::One;
}
}
}
@@ -828,6 +831,10 @@ impl PaintApp {
let mut y = p1.y;
let mut width = p2.x - p1.x;
let mut height = p2.y - p1.y;
if width < 1.0 || height < 1.0 {
self.control_state = ControlState::Zero;
return;
}
if width < 0.0 && height < 0.0 {
x = p2.x;
y = p2.y;