From 6db8941b675df239e0b8e98507574c2608aa6579 Mon Sep 17 00:00:00 2001 From: yeqing Date: Fri, 6 Mar 2026 15:39:57 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=9F=A9=E5=BD=A2=E6=A1=86=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E5=87=BA=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mscanvas.rs | 46 +++++++++++++++++++++++++++++++++++++--------- src/paint.rs | 11 +++++++++-- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/mscanvas.rs b/src/mscanvas.rs index 3859917..551658f 100644 --- a/src/mscanvas.rs +++ b/src/mscanvas.rs @@ -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); } } } diff --git a/src/paint.rs b/src/paint.rs index 21d18c5..b984566 100644 --- a/src/paint.rs +++ b/src/paint.rs @@ -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;