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; let b = n as u8;
Self { r, g, b, a: 0xff } 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)] #[derive(Clone, Copy, PartialEq)]
@@ -1375,18 +1379,42 @@ impl MSCanvas {
} }
pub fn draw_rect_selection(&mut self, x: i32, y: i32, rect: &RectSelection) { 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 dy in 0..h {
for dx in 0..w { let src_start = ((dy + src_offset_y) * rect.w as usize + src_offset_x) * 4;
let src_idx = ((dy * rect.w + dx) * 4) as usize; let dst_start = ((y + dy) * width + x) * 4;
let dst_idx = (((y + dy) * self.width + x + dx) * 4) as usize;
self.pixels[dst_idx] = rect.pixels[src_idx]; // 使用 unsafe 块进一步优化(如果确定索引安全)
self.pixels[dst_idx + 1] = rect.pixels[src_idx + 1]; unsafe {
self.pixels[dst_idx + 2] = rect.pixels[src_idx + 2]; let src_slice = &rect.pixels.get_unchecked(src_start..src_start + w * 4);
self.pixels[dst_idx + 3] = rect.pixels[src_idx + 3]; 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)); .height(Length::Fixed(height as f32));
let canvas_area = mouse_area(image_widget) 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_release(|pos| Message::MouseReleased(pos))
.on_move(|pos| Message::MouseMoved(pos)) .on_move(|pos| Message::MouseMoved(pos))
.on_double_click(|pos| Message::MouseDoubleClick(pos)) .on_double_click(|pos| Message::MouseDoubleClick(pos))
@@ -811,7 +811,10 @@ impl PaintApp {
self.control_state = ControlState::Two; self.control_state = ControlState::Two;
} else { } else {
self.release_rect_selection(); 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 y = p1.y;
let mut width = p2.x - p1.x; let mut width = p2.x - p1.x;
let mut height = p2.y - p1.y; 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 { if width < 0.0 && height < 0.0 {
x = p2.x; x = p2.x;
y = p2.y; y = p2.y;