feat: 实现选择虚线框效果

This commit is contained in:
2026-03-04 00:58:35 +08:00
parent 09d29473bb
commit de76574654
2 changed files with 194 additions and 11 deletions

View File

@@ -145,16 +145,19 @@ impl MSCanvas {
}
}
pub fn line_width(&mut self, line_width: i32) {
pub fn line_width(&mut self, line_width: i32) -> &mut Self {
self.line_width = line_width;
self
}
pub fn fill_color(&mut self, color: MSColor) {
pub fn fill_color(&mut self, color: MSColor) -> &mut Self {
self.fill_color = color;
self
}
pub fn stroke_color(&mut self, color: MSColor) {
pub fn stroke_color(&mut self, color: MSColor) -> &mut Self {
self.stroke_color = color;
self
}
pub fn size(&self) -> (i32, i32) {
(self.width, self.height)
@@ -221,6 +224,31 @@ impl MSCanvas {
self.pixels[index + 3],
)
}
pub fn overlay_pixels(&mut self, canvas: &MSCanvas) -> Vec<u8> {
let mut pixels = canvas.get_pixels();
let width = canvas.width.min(self.width);
let height = canvas.height.min(self.height);
for y in 0..height {
for x in 0..width {
let index = ((y * width + x) * 4) as usize;
// 跳过透明像素
if self.pixels[index + 3] == 0 {
continue;
}
pixels[index] = self.pixels[index];
pixels[index + 1] = self.pixels[index + 1];
pixels[index + 2] = self.pixels[index + 2];
pixels[index + 3] = self.pixels[index + 3];
}
}
pixels
}
}
#[allow(unused)]
@@ -267,7 +295,26 @@ impl MSCanvas {
self.pixels[index + 3] = self.stroke_color.a; // A
}
fn fill_row(&mut self, xs: i32, xe: i32, y: i32) {
fn draw_column_with_color(&mut self, ys: i32, ye: i32, x: i32, color: MSColor) {
if x < 0 || x >= self.width {
return;
}
let ys = ys.clamp(0, self.height - 1);
let ye = ye.clamp(0, self.height);
for y in ys..ye {
let index = ((y * self.width + x) * 4) as usize;
// 写入 RGBA 数据
// 注意Color 的 r, g, b, a 是 0.0 - 1.0,需要转为 0 - 255
self.pixels[index] = color.r; // R
self.pixels[index + 1] = color.g; // G
self.pixels[index + 2] = color.b; // B
self.pixels[index + 3] = color.a; // A
}
}
fn draw_row_with_color(&mut self, xs: i32, xe: i32, y: i32, color: MSColor) {
if y < 0 || y >= self.height {
return;
}
@@ -279,20 +326,36 @@ impl MSCanvas {
// 写入 RGBA 数据
// 注意Color 的 r, g, b, a 是 0.0 - 1.0,需要转为 0 - 255
self.pixels[index] = self.fill_color.r; // R
self.pixels[index + 1] = self.fill_color.g; // G
self.pixels[index + 2] = self.fill_color.b; // B
self.pixels[index + 3] = self.fill_color.a; // A
self.pixels[index] = color.r; // R
self.pixels[index + 1] = color.g; // G
self.pixels[index + 2] = color.b; // B
self.pixels[index + 3] = color.a; // A
}
}
fn fill_column(&mut self, ys: i32, ye: i32, x: i32) {
self.draw_column_with_color(ys, ye, x, self.fill_color);
}
fn fill_row(&mut self, xs: i32, xe: i32, y: i32) {
self.draw_row_with_color(xs, xe, y, self.fill_color);
}
fn stroke_column(&mut self, ys: i32, ye: i32, x: i32) {
self.draw_column_with_color(ys, ye, x, self.stroke_color);
}
fn stroke_row(&mut self, xs: i32, xe: i32, y: i32) {
self.draw_row_with_color(xs, xe, y, self.stroke_color);
}
pub fn fill_pixels(&mut self, points: Vec<Point>) {
for point in points {
self.fill_pixel_at(point);
}
}
pub fn stroke_cross_color(&mut self, point: Point) {
pub fn stroke_cross(&mut self, point: Point) {
let Point { x, y } = point;
let r = 10;
for dy in -r..=r {
@@ -875,10 +938,71 @@ impl MSCanvas {
self.stroke_rect(x as i32, y as i32, width as i32, height as i32);
}
pub fn stroke_dashed_rect(
&mut self,
x: i32,
y: i32,
width: i32,
height: i32,
dash_length: i32,
gap_length: i32,
) {
let mut is_dash = true;
// 上下两边边框
for dx in (x..x + width).step_by((dash_length + gap_length) as usize) {
if is_dash {
self.stroke_row(dx, dx + dash_length, y);
self.stroke_row(dx, dx + dash_length, y + height - 1);
}
is_dash = !is_dash;
}
// 左右两边边框
for dy in (y..y + height).step_by((dash_length + gap_length) as usize) {
if is_dash {
self.stroke_column(dy, dy + dash_length, x);
self.stroke_column(dy, dy + dash_length, x + width - 1);
}
is_dash = !is_dash;
}
}
pub fn stroke_dashed_rect1(&mut self, p1: Point, p2: Point, dash_length: i32, gap_length: i32) {
let mut x = p1.x;
let mut y = p1.y;
let mut width = (p2.x - p1.x);
let mut height = (p2.y - p1.y);
if width < 0.0 && height < 0.0 {
x = p2.x;
y = p2.y;
width = (p1.x - p2.x);
height = (p1.y - p2.y);
} else if width < 0.0 {
x += width;
width = -width;
} else if height < 0.0 {
y += height;
height = -height;
}
self.stroke_dashed_rect(
x as i32,
y as i32,
width as i32,
height as i32,
dash_length,
gap_length,
);
}
pub fn clear(&mut self) {
self.pixels.fill(255);
}
pub fn clear_zero(&mut self) {
self.pixels.fill(0);
}
pub fn clear_row(&mut self, xs: i32, xe: i32, y: i32) {
if y < 0 || y >= self.height {
return;