image_renderer/
canvas.rs

1//! Canvas 绘制上下文
2//!
3//! 提供类似 skia-safe 风格的绘制 API
4
5use crate::clip::{ClipOp, ClipStack};
6use crate::color::Color;
7use crate::error::{DrawError, Result};
8use crate::font::TextStyle;
9use crate::matrix::{CanvasState, Matrix};
10use crate::paint::{Paint, PaintStyle};
11use crate::path::Path;
12use crate::point::Point;
13use crate::rect::Rect;
14use crate::surface::Surface;
15use image::Rgba;
16use imageproc::drawing::{
17    draw_filled_rect_mut, draw_hollow_rect_mut, draw_line_segment_mut, draw_text_mut,
18};
19use imageproc::rect::Rect as ImageprocRect;
20
21/// Canvas 绘制上下文
22///
23/// 提供在图片表面上进行各种绘制操作的能力
24pub struct Canvas {
25    /// 底层图片表面
26    surface: Surface,
27    /// 状态栈,用于保存和恢复变换和裁剪状态
28    state_stack: Vec<CanvasState>,
29    /// 当前变换矩阵
30    current_matrix: Matrix,
31    /// 裁剪栈
32    clip_stack: ClipStack,
33}
34
35impl Canvas {
36    /// 创建新的 Canvas
37    pub fn new(width: u32, height: u32) -> Result<Self> {
38        let surface = Surface::new(width, height)?;
39        Ok(Self {
40            surface,
41            state_stack: Vec::new(),
42            current_matrix: Matrix::identity(),
43            clip_stack: ClipStack::new(),
44        })
45    }
46
47    /// 创建指定背景色的 Canvas
48    pub fn new_with_color(width: u32, height: u32, color: Color) -> Result<Self> {
49        let surface = Surface::new_with_color(width, height, color.to_rgba())?;
50        Ok(Self {
51            surface,
52            state_stack: Vec::new(),
53            current_matrix: Matrix::identity(),
54            clip_stack: ClipStack::new(),
55        })
56    }
57
58    /// 从已有的 Surface 创建 Canvas
59    pub fn from_surface(surface: Surface) -> Self {
60        Self {
61            surface,
62            state_stack: Vec::new(),
63            current_matrix: Matrix::identity(),
64            clip_stack: ClipStack::new(),
65        }
66    }
67
68    /// 从文件加载图片并创建 Canvas
69    pub fn from_file<P: AsRef<std::path::Path>>(path: P) -> Result<Self> {
70        let surface = Surface::from_file(path)?;
71        Ok(Self {
72            surface,
73            state_stack: Vec::new(),
74            current_matrix: Matrix::identity(),
75            clip_stack: ClipStack::new(),
76        })
77    }
78
79    /// 获取 Canvas 宽度
80    pub fn width(&self) -> u32 {
81        self.surface.width()
82    }
83
84    /// 获取 Canvas 高度
85    pub fn height(&self) -> u32 {
86        self.surface.height()
87    }
88
89    /// 获取 Canvas 尺寸
90    pub fn dimensions(&self) -> (u32, u32) {
91        self.surface.dimensions()
92    }
93
94    /// 清空 Canvas 为指定颜色
95    pub fn clear(&mut self, color: Color) {
96        self.surface.clear(color.to_rgba());
97    }
98
99    /// 保存到文件
100    pub fn save_to_file<P: AsRef<std::path::Path>>(&self, path: P) -> Result<()> {
101        self.surface.save(path)?;
102        Ok(())
103    }
104
105    /// 导出为 PNG 字节数据
106    pub fn to_png_bytes(&self) -> Result<Vec<u8>> {
107        Ok(self.surface.to_png_bytes()?)
108    }
109
110    /// 导出为 JPEG 字节数据
111    pub fn to_jpeg_bytes(&self, quality: u8) -> Result<Vec<u8>> {
112        Ok(self.surface.to_jpeg_bytes(quality)?)
113    }
114
115    /// 获取底层 Surface
116    pub fn surface(&self) -> &Surface {
117        &self.surface
118    }
119
120    /// 获取可变的底层 Surface
121    pub fn surface_mut(&mut self) -> &mut Surface {
122        &mut self.surface
123    }
124
125    /// 绘制点
126    pub fn draw_point(&mut self, point: Point, paint: &Paint) {
127        let x = point.x;
128        let y = point.y;
129
130        if x >= 0 && y >= 0 {
131            let x = x as u32;
132            let y = y as u32;
133            if x < self.width() && y < self.height() {
134                self.surface.put_pixel(x, y, paint.color().to_rgba());
135            }
136        }
137    }
138
139    /// 绘制线段
140    pub fn draw_line(&mut self, start: Point, end: Point, paint: &Paint) {
141        let start_f = (start.x as f32, start.y as f32);
142        let end_f = (end.x as f32, end.y as f32);
143
144        draw_line_segment_mut(
145            self.surface.image_mut(),
146            start_f,
147            end_f,
148            paint.color().to_rgba(),
149        );
150    }
151
152    /// 绘制矩形
153    pub fn draw_rect(&mut self, rect: Rect, paint: &Paint) {
154        let imageproc_rect = ImageprocRect::at(rect.x, rect.y).of_size(rect.width, rect.height);
155
156        match paint.style() {
157            PaintStyle::Fill => {
158                draw_filled_rect_mut(
159                    self.surface.image_mut(),
160                    imageproc_rect,
161                    paint.color().to_rgba(),
162                );
163            }
164            PaintStyle::Stroke => {
165                // 绘制空心矩形
166                draw_hollow_rect_mut(
167                    self.surface.image_mut(),
168                    imageproc_rect,
169                    paint.color().to_rgba(),
170                );
171
172                // 如果线宽大于1,需要绘制多层
173                let stroke_width = paint.stroke_width() as i32;
174                for i in 1..stroke_width {
175                    let inner_rect = ImageprocRect::at(rect.x + i, rect.y + i).of_size(
176                        rect.width.saturating_sub((i * 2) as u32),
177                        rect.height.saturating_sub((i * 2) as u32),
178                    );
179                    if inner_rect.width() > 0 && inner_rect.height() > 0 {
180                        draw_hollow_rect_mut(
181                            self.surface.image_mut(),
182                            inner_rect,
183                            paint.color().to_rgba(),
184                        );
185                    }
186                }
187            }
188            PaintStyle::FillAndStroke => {
189                // 先填充
190                draw_filled_rect_mut(
191                    self.surface.image_mut(),
192                    imageproc_rect,
193                    paint.color().to_rgba(),
194                );
195                // 再描边
196                draw_hollow_rect_mut(
197                    self.surface.image_mut(),
198                    imageproc_rect,
199                    paint.color().to_rgba(),
200                );
201            }
202        }
203    }
204
205    /// 绘制圆角矩形
206    pub fn draw_rounded_rect(&mut self, rect: Rect, radius: f32, paint: &Paint) {
207        // 使用四个圆弧和四条直线来绘制圆角矩形
208        let r = radius.min((rect.width as f32 / 2.0).min(rect.height as f32 / 2.0));
209
210        if r <= 0.0 {
211            self.draw_rect(rect, paint);
212            return;
213        }
214
215        let color = paint.color().to_rgba();
216
217        // 简化实现:绘制矩形主体和四个角
218        match paint.style() {
219            PaintStyle::Fill | PaintStyle::FillAndStroke => {
220                // 填充中心矩形
221                let center_rect = ImageprocRect::at(rect.x, rect.y + r as i32)
222                    .of_size(rect.width, rect.height - (r * 2.0) as u32);
223                draw_filled_rect_mut(self.surface.image_mut(), center_rect, color);
224
225                // 填充上下矩形
226                let top_rect = ImageprocRect::at(rect.x + r as i32, rect.y)
227                    .of_size(rect.width - (r * 2.0) as u32, r as u32);
228                draw_filled_rect_mut(self.surface.image_mut(), top_rect, color);
229
230                let bottom_rect =
231                    ImageprocRect::at(rect.x + r as i32, rect.y + rect.height as i32 - r as i32)
232                        .of_size(rect.width - (r * 2.0) as u32, r as u32);
233                draw_filled_rect_mut(self.surface.image_mut(), bottom_rect, color);
234
235                // 绘制四个圆角
236                self.draw_circle_corner(rect.x + r as i32, rect.y + r as i32, r, color, true);
237                self.draw_circle_corner(
238                    rect.x + rect.width as i32 - r as i32,
239                    rect.y + r as i32,
240                    r,
241                    color,
242                    true,
243                );
244                self.draw_circle_corner(
245                    rect.x + r as i32,
246                    rect.y + rect.height as i32 - r as i32,
247                    r,
248                    color,
249                    true,
250                );
251                self.draw_circle_corner(
252                    rect.x + rect.width as i32 - r as i32,
253                    rect.y + rect.height as i32 - r as i32,
254                    r,
255                    color,
256                    true,
257                );
258            }
259            PaintStyle::Stroke => {
260                // 描边实现
261                self.draw_rect(rect, paint);
262            }
263        }
264    }
265
266    /// 辅助方法:绘制圆形区域
267    fn draw_circle_corner(&mut self, cx: i32, cy: i32, radius: f32, color: Rgba<u8>, fill: bool) {
268        let r = radius as i32;
269        for dy in -r..=r {
270            for dx in -r..=r {
271                let dist_sq = dx * dx + dy * dy;
272                let r_sq = (radius * radius) as i32;
273
274                if fill && dist_sq <= r_sq {
275                    let x = cx + dx;
276                    let y = cy + dy;
277                    if x >= 0 && y >= 0 {
278                        self.surface.put_pixel(x as u32, y as u32, color);
279                    }
280                }
281            }
282        }
283    }
284
285    /// 绘制圆形
286    pub fn draw_circle(&mut self, center: Point, radius: f32, paint: &Paint) {
287        let color = paint.color().to_rgba();
288        let r = radius as i32;
289
290        match paint.style() {
291            PaintStyle::Fill | PaintStyle::FillAndStroke => {
292                // 填充圆形
293                for dy in -r..=r {
294                    for dx in -r..=r {
295                        let dist_sq = dx * dx + dy * dy;
296                        let r_sq = (radius * radius) as i32;
297
298                        if dist_sq <= r_sq {
299                            let x = center.x + dx;
300                            let y = center.y + dy;
301                            if x >= 0 && y >= 0 {
302                                self.surface.put_pixel(x as u32, y as u32, color);
303                            }
304                        }
305                    }
306                }
307            }
308            PaintStyle::Stroke => {
309                // 描边圆形
310                let stroke_width = paint.stroke_width();
311                let inner_r = (radius - stroke_width).max(0.0);
312                let inner_r_sq = (inner_r * inner_r) as i32;
313                let outer_r_sq = (radius * radius) as i32;
314
315                for dy in -r..=r {
316                    for dx in -r..=r {
317                        let dist_sq = dx * dx + dy * dy;
318
319                        if dist_sq <= outer_r_sq && dist_sq >= inner_r_sq {
320                            let x = center.x + dx;
321                            let y = center.y + dy;
322                            if x >= 0 && y >= 0 {
323                                self.surface.put_pixel(x as u32, y as u32, color);
324                            }
325                        }
326                    }
327                }
328            }
329        }
330    }
331
332    /// 绘制椭圆
333    pub fn draw_oval(&mut self, rect: Rect, paint: &Paint) {
334        let cx = rect.x + rect.width as i32 / 2;
335        let cy = rect.y + rect.height as i32 / 2;
336        let rx = rect.width as f32 / 2.0;
337        let ry = rect.height as f32 / 2.0;
338
339        let color = paint.color().to_rgba();
340
341        match paint.style() {
342            PaintStyle::Fill | PaintStyle::FillAndStroke => {
343                // 填充椭圆
344                for y in rect.y..(rect.y + rect.height as i32) {
345                    for x in rect.x..(rect.x + rect.width as i32) {
346                        let dx = (x - cx) as f32;
347                        let dy = (y - cy) as f32;
348
349                        if (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry) <= 1.0 {
350                            if x >= 0 && y >= 0 {
351                                self.surface.put_pixel(x as u32, y as u32, color);
352                            }
353                        }
354                    }
355                }
356            }
357            PaintStyle::Stroke => {
358                // 描边椭圆
359                let stroke_width = paint.stroke_width();
360                let inner_rx = (rx - stroke_width).max(0.0);
361                let inner_ry = (ry - stroke_width).max(0.0);
362
363                for y in rect.y..(rect.y + rect.height as i32) {
364                    for x in rect.x..(rect.x + rect.width as i32) {
365                        let dx = (x - cx) as f32;
366                        let dy = (y - cy) as f32;
367
368                        let outer = (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry);
369                        let inner =
370                            (dx * dx) / (inner_rx * inner_rx) + (dy * dy) / (inner_ry * inner_ry);
371
372                        if outer <= 1.0 && inner >= 1.0 {
373                            if x >= 0 && y >= 0 {
374                                self.surface.put_pixel(x as u32, y as u32, color);
375                            }
376                        }
377                    }
378                }
379            }
380        }
381    }
382
383    /// 绘制文本
384    pub fn draw_text(
385        &mut self,
386        text: &str,
387        position: Point,
388        text_style: &TextStyle,
389        paint: &Paint,
390    ) {
391        let scale = text_style.scale();
392        let font = text_style.font.inner();
393        let color = paint.color().to_rgba();
394
395        draw_text_mut(
396            self.surface.image_mut(),
397            color,
398            position.x,
399            position.y,
400            scale,
401            font,
402            text,
403        );
404    }
405
406    /// 绘制图片
407    pub fn draw_image(&mut self, image: &Surface, position: Point) -> Result<()> {
408        self.draw_image_rect(
409            image,
410            None,
411            Rect::new(position.x, position.y, image.width(), image.height()),
412        )
413    }
414
415    /// 绘制图片的指定区域到指定位置
416    pub fn draw_image_rect(
417        &mut self,
418        image: &Surface,
419        src_rect: Option<Rect>,
420        dst_rect: Rect,
421    ) -> Result<()> {
422        // 获取源矩形
423        let src = src_rect.unwrap_or_else(|| Rect::new(0, 0, image.width(), image.height()));
424
425        // 验证源矩形
426        if src.x < 0
427            || src.y < 0
428            || src.x as u32 + src.width > image.width()
429            || src.y as u32 + src.height > image.height()
430        {
431            return Err(DrawError::InvalidCoordinates { x: src.x, y: src.y });
432        }
433
434        // 如果需要缩放
435        let src_image = if src.width != dst_rect.width || src.height != dst_rect.height {
436            // 先裁剪
437            let cropped = image.crop(src.x as u32, src.y as u32, src.width, src.height)?;
438            // 再缩放
439            cropped.resize(dst_rect.width, dst_rect.height)?
440        } else {
441            // 只裁剪
442            image.crop(src.x as u32, src.y as u32, src.width, src.height)?
443        };
444
445        // 复制像素
446        for y in 0..dst_rect.height {
447            for x in 0..dst_rect.width {
448                let src_pixel = src_image.get_pixel(x, y).unwrap();
449                let dst_x = dst_rect.x + x as i32;
450                let dst_y = dst_rect.y + y as i32;
451
452                if dst_x >= 0
453                    && dst_y >= 0
454                    && (dst_x as u32) < self.width()
455                    && (dst_y as u32) < self.height()
456                {
457                    // Alpha 混合
458                    self.blend_pixel(dst_x as u32, dst_y as u32, src_pixel);
459                }
460            }
461        }
462
463        Ok(())
464    }
465
466    /// Alpha 混合像素
467    fn blend_pixel(&mut self, x: u32, y: u32, src: Rgba<u8>) {
468        if let Some(dst) = self.surface.get_pixel(x, y) {
469            let src_alpha = src[3] as f32 / 255.0;
470            let dst_alpha = dst[3] as f32 / 255.0;
471
472            if src_alpha == 0.0 {
473                return;
474            }
475
476            if src_alpha == 1.0 {
477                self.surface.put_pixel(x, y, src);
478                return;
479            }
480
481            // Alpha 混合
482            let out_alpha = src_alpha + dst_alpha * (1.0 - src_alpha);
483
484            if out_alpha == 0.0 {
485                return;
486            }
487
488            let r = ((src[0] as f32 * src_alpha + dst[0] as f32 * dst_alpha * (1.0 - src_alpha))
489                / out_alpha) as u8;
490            let g = ((src[1] as f32 * src_alpha + dst[1] as f32 * dst_alpha * (1.0 - src_alpha))
491                / out_alpha) as u8;
492            let b = ((src[2] as f32 * src_alpha + dst[2] as f32 * dst_alpha * (1.0 - src_alpha))
493                / out_alpha) as u8;
494            let a = (out_alpha * 255.0) as u8;
495
496            self.surface.put_pixel(x, y, Rgba([r, g, b, a]));
497        }
498    }
499
500    /// 九宫格绘制图片(类似 skia-safe 的 draw_image_nine)
501    ///
502    /// 将图片分割成 3x3 的九宫格,智能拉伸以适应目标区域。
503    /// 四个角落保持不变,边缘单向拉伸,中心区域双向拉伸。
504    ///
505    /// # 参数
506    ///
507    /// * `image` - 要绘制的图片
508    /// * `center` - 中心矩形区域,定义九宫格的分割方式
509    /// * `dst` - 目标绘制区域
510    ///
511    /// # 九宫格分割示例
512    ///
513    /// ```text
514    /// ┌─────────┬──────────┬─────────┐
515    /// │  角落1  │  上边缘  │  角落2  │
516    /// │ (固定)  │ (水平拉) │ (固定)  │
517    /// ├─────────┼──────────┼─────────┤
518    /// │ 左边缘  │  中心    │ 右边缘  │
519    /// │ (垂直拉)│ (双向拉) │ (垂直拉)│
520    /// ├─────────┼──────────┼─────────┤
521    /// │  角落3  │  下边缘  │  角落4  │
522    /// │ (固定)  │ (水平拉) │ (固定)  │
523    /// └─────────┴──────────┴─────────┘
524    /// ```
525    pub fn draw_image_nine(&mut self, image: &Surface, center: Rect, dst: Rect) -> Result<()> {
526        // 验证 center 矩形的有效性
527        if center.x < 0
528            || center.y < 0
529            || center.x as u32 >= image.width()
530            || center.y as u32 >= image.height()
531            || center.x as u32 + center.width > image.width()
532            || center.y as u32 + center.height > image.height()
533        {
534            return Err(DrawError::InvalidCoordinates {
535                x: center.x,
536                y: center.y,
537            });
538        }
539
540        // 计算源图片的九个区域
541        let src_left = center.x as u32;
542        let src_top = center.y as u32;
543        let src_right = image.width() - (center.x as u32 + center.width);
544        let src_bottom = image.height() - (center.y as u32 + center.height);
545        let src_center_width = center.width;
546        let src_center_height = center.height;
547
548        // 计算目标区域的九个区域
549        // 如果目标区域太小,角落区域可能需要缩小
550        let dst_left = src_left.min(dst.width / 3);
551        let dst_top = src_top.min(dst.height / 3);
552        let dst_right = src_right.min(dst.width / 3);
553        let dst_bottom = src_bottom.min(dst.height / 3);
554
555        let dst_center_width = dst.width.saturating_sub(dst_left + dst_right);
556        let dst_center_height = dst.height.saturating_sub(dst_top + dst_bottom);
557
558        // 绘制九个区域
559
560        // 1. 左上角(固定大小)
561        if dst_left > 0 && dst_top > 0 {
562            let src_rect = Rect::new(0, 0, src_left, src_top);
563            let dst_rect = Rect::new(dst.x, dst.y, dst_left, dst_top);
564            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
565        }
566
567        // 2. 上边缘(水平拉伸)
568        if dst_center_width > 0 && dst_top > 0 {
569            let src_rect = Rect::new(src_left as i32, 0, src_center_width, src_top);
570            let dst_rect = Rect::new(dst.x + dst_left as i32, dst.y, dst_center_width, dst_top);
571            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
572        }
573
574        // 3. 右上角(固定大小)
575        if dst_right > 0 && dst_top > 0 {
576            let src_rect = Rect::new((image.width() - src_right) as i32, 0, src_right, src_top);
577            let dst_rect = Rect::new(
578                dst.x + (dst.width - dst_right) as i32,
579                dst.y,
580                dst_right,
581                dst_top,
582            );
583            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
584        }
585
586        // 4. 左边缘(垂直拉伸)
587        if dst_left > 0 && dst_center_height > 0 {
588            let src_rect = Rect::new(0, src_top as i32, src_left, src_center_height);
589            let dst_rect = Rect::new(dst.x, dst.y + dst_top as i32, dst_left, dst_center_height);
590            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
591        }
592
593        // 5. 中心区域(双向拉伸)
594        if dst_center_width > 0 && dst_center_height > 0 {
595            let src_rect = Rect::new(
596                src_left as i32,
597                src_top as i32,
598                src_center_width,
599                src_center_height,
600            );
601            let dst_rect = Rect::new(
602                dst.x + dst_left as i32,
603                dst.y + dst_top as i32,
604                dst_center_width,
605                dst_center_height,
606            );
607            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
608        }
609
610        // 6. 右边缘(垂直拉伸)
611        if dst_right > 0 && dst_center_height > 0 {
612            let src_rect = Rect::new(
613                (image.width() - src_right) as i32,
614                src_top as i32,
615                src_right,
616                src_center_height,
617            );
618            let dst_rect = Rect::new(
619                dst.x + (dst.width - dst_right) as i32,
620                dst.y + dst_top as i32,
621                dst_right,
622                dst_center_height,
623            );
624            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
625        }
626
627        // 7. 左下角(固定大小)
628        if dst_left > 0 && dst_bottom > 0 {
629            let src_rect = Rect::new(
630                0,
631                (image.height() - src_bottom) as i32,
632                src_left,
633                src_bottom,
634            );
635            let dst_rect = Rect::new(
636                dst.x,
637                dst.y + (dst.height - dst_bottom) as i32,
638                dst_left,
639                dst_bottom,
640            );
641            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
642        }
643
644        // 8. 下边缘(水平拉伸)
645        if dst_center_width > 0 && dst_bottom > 0 {
646            let src_rect = Rect::new(
647                src_left as i32,
648                (image.height() - src_bottom) as i32,
649                src_center_width,
650                src_bottom,
651            );
652            let dst_rect = Rect::new(
653                dst.x + dst_left as i32,
654                dst.y + (dst.height - dst_bottom) as i32,
655                dst_center_width,
656                dst_bottom,
657            );
658            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
659        }
660
661        // 9. 右下角(固定大小)
662        if dst_right > 0 && dst_bottom > 0 {
663            let src_rect = Rect::new(
664                (image.width() - src_right) as i32,
665                (image.height() - src_bottom) as i32,
666                src_right,
667                src_bottom,
668            );
669            let dst_rect = Rect::new(
670                dst.x + (dst.width - dst_right) as i32,
671                dst.y + (dst.height - dst_bottom) as i32,
672                dst_right,
673                dst_bottom,
674            );
675            self.draw_image_rect(image, Some(src_rect), dst_rect)?;
676        }
677
678        Ok(())
679    }
680
681    /// 测量文本尺寸
682    pub fn measure_text(&self, text: &str, text_style: &TextStyle) -> (u32, u32) {
683        let scale = text_style.scale();
684        let font = text_style.font.inner();
685
686        let v_metrics = font.v_metrics(scale);
687        let height = (v_metrics.ascent - v_metrics.descent).ceil() as u32;
688
689        let width = font
690            .layout(text, scale, rusttype::point(0.0, 0.0))
691            .map(|g| g.position().x + g.unpositioned().h_metrics().advance_width)
692            .last()
693            .unwrap_or(0.0)
694            .ceil() as u32;
695
696        (width, height)
697    }
698
699    /// 绘制虚线
700    ///
701    /// 根据 Paint 中的虚线样式绘制虚线。如果虚线样式为 Solid,则绘制实线。
702    ///
703    /// # 参数
704    ///
705    /// * `start` - 起点
706    /// * `end` - 终点
707    /// * `paint` - 绘制样式(包含虚线模式)
708    ///
709    /// # 示例
710    ///
711    /// ```no_run
712    /// use image_renderer::{Canvas, Color, Paint, Point, paint::DashStyle};
713    ///
714    /// let mut canvas = Canvas::new(400, 300).unwrap();
715    /// let mut paint = Paint::stroke(Color::BLUE, 2.0);
716    /// paint.set_dash_style(DashStyle::ShortDash);
717    ///
718    /// canvas.draw_dashed_line(
719    ///     Point::new(50, 100),
720    ///     Point::new(350, 100),
721    ///     &paint
722    /// );
723    /// ```
724    pub fn draw_dashed_line(&mut self, start: Point, end: Point, paint: &Paint) {
725        // 如果是实线,直接使用普通绘制
726        if paint.dash_style().is_solid() {
727            self.draw_line(start, end, paint);
728            return;
729        }
730
731        // 获取虚线模式
732        let pattern = match paint.dash_pattern() {
733            Some(p) => p,
734            None => {
735                self.draw_line(start, end, paint);
736                return;
737            }
738        };
739
740        if pattern.is_empty() {
741            self.draw_line(start, end, paint);
742            return;
743        }
744
745        // 计算线段长度和方向
746        let dx = end.x - start.x;
747        let dy = end.y - start.y;
748        let length = ((dx * dx + dy * dy) as f32).sqrt();
749
750        if length == 0.0 {
751            return;
752        }
753
754        // 计算单位方向向量
755        let unit_dx = dx as f32 / length;
756        let unit_dy = dy as f32 / length;
757
758        // 遍历虚线模式绘制
759        let mut current_pos = 0.0;
760        let mut pattern_index = 0;
761        let mut is_dash = true; // 开始是实线段
762
763        while current_pos < length {
764            let segment_length = pattern[pattern_index % pattern.len()];
765            let next_pos = (current_pos + segment_length).min(length);
766
767            if is_dash {
768                // 绘制实线段
769                let seg_start = Point::new(
770                    start.x + (unit_dx * current_pos) as i32,
771                    start.y + (unit_dy * current_pos) as i32,
772                );
773                let seg_end = Point::new(
774                    start.x + (unit_dx * next_pos) as i32,
775                    start.y + (unit_dy * next_pos) as i32,
776                );
777                self.draw_line(seg_start, seg_end, paint);
778            }
779
780            current_pos = next_pos;
781            pattern_index += 1;
782            is_dash = !is_dash; // 交替实线和间隙
783        }
784    }
785
786    /// 绘制虚线矩形
787    ///
788    /// 根据 Paint 中的虚线样式绘制矩形边框。如果虚线样式为 Solid,则绘制实线矩形。
789    ///
790    /// # 参数
791    ///
792    /// * `rect` - 矩形区域
793    /// * `paint` - 绘制样式(包含虚线模式)
794    ///
795    /// # 示例
796    ///
797    /// ```no_run
798    /// use image_renderer::{Canvas, Color, Paint, Rect, paint::DashStyle};
799    ///
800    /// let mut canvas = Canvas::new(400, 300).unwrap();
801    /// let mut paint = Paint::stroke(Color::RED, 2.0);
802    /// paint.set_dash_style(DashStyle::DashDot);
803    ///
804    /// canvas.draw_dashed_rect(
805    ///     Rect::new(50, 50, 300, 200),
806    ///     &paint
807    /// );
808    /// ```
809    pub fn draw_dashed_rect(&mut self, rect: Rect, paint: &Paint) {
810        // 如果是实线,直接使用普通绘制
811        if paint.dash_style().is_solid() {
812            self.draw_rect(rect, paint);
813            return;
814        }
815
816        // 绘制四条边
817        // 上边
818        self.draw_dashed_line(
819            Point::new(rect.x, rect.y),
820            Point::new(rect.x + rect.width as i32, rect.y),
821            paint,
822        );
823
824        // 右边
825        self.draw_dashed_line(
826            Point::new(rect.x + rect.width as i32, rect.y),
827            Point::new(rect.x + rect.width as i32, rect.y + rect.height as i32),
828            paint,
829        );
830
831        // 下边
832        self.draw_dashed_line(
833            Point::new(rect.x + rect.width as i32, rect.y + rect.height as i32),
834            Point::new(rect.x, rect.y + rect.height as i32),
835            paint,
836        );
837
838        // 左边
839        self.draw_dashed_line(
840            Point::new(rect.x, rect.y + rect.height as i32),
841            Point::new(rect.x, rect.y),
842            paint,
843        );
844    }
845
846    /// 绘制虚线圆角矩形
847    ///
848    /// 根据 Paint 中的虚线样式绘制圆角矩形边框。如果虚线样式为 Solid,则绘制实线圆角矩形。
849    ///
850    /// # 参数
851    ///
852    /// * `rect` - 矩形区域
853    /// * `radius` - 圆角半径
854    /// * `paint` - 绘制样式(包含虚线模式)
855    ///
856    /// # 示例
857    ///
858    /// ```no_run
859    /// use image_renderer::{Canvas, Color, Paint, Rect, paint::DashStyle};
860    ///
861    /// let mut canvas = Canvas::new(400, 300).unwrap();
862    /// let mut paint = Paint::stroke(Color::BLUE, 2.0);
863    /// paint.set_dash_style(DashStyle::ShortDash);
864    ///
865    /// canvas.draw_dashed_rounded_rect(
866    ///     Rect::new(50, 50, 300, 200),
867    ///     20.0,
868    ///     &paint
869    /// );
870    /// ```
871    pub fn draw_dashed_rounded_rect(&mut self, rect: Rect, radius: f32, paint: &Paint) {
872        // 限制圆角半径
873        let r = radius.min((rect.width as f32 / 2.0).min(rect.height as f32 / 2.0));
874
875        if r <= 0.0 {
876            self.draw_dashed_rect(rect, paint);
877            return;
878        }
879
880        // 如果是实线,使用普通圆角矩形绘制
881        if paint.dash_style().is_solid() {
882            self.draw_rounded_rect(rect, r, paint);
883            return;
884        }
885
886        // 绘制四条直边(虚线)
887        // 上边
888        self.draw_dashed_line(
889            Point::new(rect.x + r as i32, rect.y),
890            Point::new(rect.x + rect.width as i32 - r as i32, rect.y),
891            paint,
892        );
893
894        // 右边
895        self.draw_dashed_line(
896            Point::new(rect.x + rect.width as i32, rect.y + r as i32),
897            Point::new(
898                rect.x + rect.width as i32,
899                rect.y + rect.height as i32 - r as i32,
900            ),
901            paint,
902        );
903
904        // 下边
905        self.draw_dashed_line(
906            Point::new(
907                rect.x + rect.width as i32 - r as i32,
908                rect.y + rect.height as i32,
909            ),
910            Point::new(rect.x + r as i32, rect.y + rect.height as i32),
911            paint,
912        );
913
914        // 左边
915        self.draw_dashed_line(
916            Point::new(rect.x, rect.y + rect.height as i32 - r as i32),
917            Point::new(rect.x, rect.y + r as i32),
918            paint,
919        );
920
921        // 绘制四个圆角(虚线弧)
922        // 左上角
923        self.draw_dashed_arc(
924            Point::new(rect.x + r as i32, rect.y + r as i32),
925            r,
926            180.0,
927            270.0,
928            paint,
929        );
930
931        // 右上角
932        self.draw_dashed_arc(
933            Point::new(rect.x + rect.width as i32 - r as i32, rect.y + r as i32),
934            r,
935            270.0,
936            360.0,
937            paint,
938        );
939
940        // 右下角
941        self.draw_dashed_arc(
942            Point::new(
943                rect.x + rect.width as i32 - r as i32,
944                rect.y + rect.height as i32 - r as i32,
945            ),
946            r,
947            0.0,
948            90.0,
949            paint,
950        );
951
952        // 左下角
953        self.draw_dashed_arc(
954            Point::new(rect.x + r as i32, rect.y + rect.height as i32 - r as i32),
955            r,
956            90.0,
957            180.0,
958            paint,
959        );
960    }
961
962    /// 绘制虚线圆弧
963    ///
964    /// 根据 Paint 中的虚线样式绘制圆弧。
965    ///
966    /// # 参数
967    ///
968    /// * `center` - 圆心
969    /// * `radius` - 半径
970    /// * `start_angle` - 起始角度(度数,0度为3点钟方向)
971    /// * `end_angle` - 结束角度(度数)
972    /// * `paint` - 绘制样式(包含虚线模式)
973    fn draw_dashed_arc(
974        &mut self,
975        center: Point,
976        radius: f32,
977        start_angle: f32,
978        end_angle: f32,
979        paint: &Paint,
980    ) {
981        // 获取虚线模式
982        let pattern = match paint.dash_pattern() {
983            Some(p) if !p.is_empty() => p,
984            _ => {
985                // 如果没有虚线模式,绘制实线弧
986                self.draw_arc_solid(center, radius, start_angle, end_angle, paint);
987                return;
988            }
989        };
990
991        // 计算弧长
992        let angle_range = (end_angle - start_angle).abs();
993        let arc_length = (angle_range.to_radians() * radius) as f32;
994
995        if arc_length <= 0.0 {
996            return;
997        }
998
999        // 沿着弧线绘制虚线
1000        let mut current_length = 0.0;
1001        let mut pattern_index = 0;
1002        let mut is_dash = true;
1003
1004        while current_length < arc_length {
1005            let segment_length = pattern[pattern_index % pattern.len()];
1006            let next_length = (current_length + segment_length).min(arc_length);
1007
1008            if is_dash {
1009                // 计算起始和结束角度
1010                let seg_start_angle = start_angle + (current_length / arc_length) * angle_range;
1011                let seg_end_angle = start_angle + (next_length / arc_length) * angle_range;
1012
1013                // 绘制弧段
1014                self.draw_arc_segment(center, radius, seg_start_angle, seg_end_angle, paint);
1015            }
1016
1017            current_length = next_length;
1018            pattern_index += 1;
1019            is_dash = !is_dash;
1020        }
1021    }
1022
1023    /// 绘制实线圆弧段
1024    fn draw_arc_solid(
1025        &mut self,
1026        center: Point,
1027        radius: f32,
1028        start_angle: f32,
1029        end_angle: f32,
1030        paint: &Paint,
1031    ) {
1032        self.draw_arc_segment(center, radius, start_angle, end_angle, paint);
1033    }
1034
1035    /// 绘制圆弧段(使用点连线)
1036    fn draw_arc_segment(
1037        &mut self,
1038        center: Point,
1039        radius: f32,
1040        start_angle: f32,
1041        end_angle: f32,
1042        paint: &Paint,
1043    ) {
1044        // 计算需要的点数(极高密度以获得抗锯齿效果)
1045        // 使用超精细计算:通过极高的点密度模拟抗锯齿
1046        let angle_range = (end_angle - start_angle).abs();
1047        let arc_length = angle_range.to_radians() * radius;
1048
1049        // 使用极高的点密度来模拟抗锯齿效果
1050        // 每0.25像素一个点,确保圆弧足够平滑
1051        let points_per_pixel = 4.0; // 每像素4个点
1052        let num_points = (arc_length * points_per_pixel)
1053            .ceil()
1054            .max(angle_range * 2.0)
1055            .max(10.0) as i32;
1056
1057        // 生成弧线上的点
1058        let mut points = Vec::new();
1059        for i in 0..=num_points {
1060            let t = i as f32 / num_points as f32;
1061            let angle = start_angle + t * (end_angle - start_angle);
1062            let rad = angle.to_radians();
1063
1064            let x = center.x + (radius * rad.cos()) as i32;
1065            let y = center.y + (radius * rad.sin()) as i32;
1066            points.push(Point::new(x, y));
1067        }
1068
1069        // 使用线段连接点,保持线宽一致
1070        for i in 0..points.len() - 1 {
1071            self.draw_line(points[i], points[i + 1], paint);
1072        }
1073    }
1074
1075    /// 绘制自定义边框的矩形(支持每条边独立配置,每个角独立圆角)
1076    ///
1077    /// # 参数
1078    ///
1079    /// * `rect` - 矩形区域
1080    /// * `border` - 边框配置(每条边可独立设置颜色、线宽、虚线样式)
1081    /// * `radius` - 圆角配置(每个角可独立设置圆角半径)
1082    ///
1083    /// # 示例
1084    ///
1085    /// ```no_run
1086    /// use image_renderer::{Canvas, Color, Border, BorderSide, BorderRadius, DashStyle, Rect};
1087    ///
1088    /// let mut canvas = Canvas::new(400, 300).unwrap();
1089    ///
1090    /// // 创建不同样式的边框
1091    /// let border = Border::new(
1092    ///     BorderSide::solid(Color::RED, 2.0),           // 上边:红色实线
1093    ///     BorderSide::dashed(Color::BLUE, 3.0, DashStyle::ShortDash), // 右边:蓝色虚线
1094    ///     BorderSide::solid(Color::GREEN, 2.0),         // 下边:绿色实线
1095    ///     BorderSide::dashed(Color::YELLOW, 3.0, DashStyle::Dot),     // 左边:黄色点线
1096    /// );
1097    ///
1098    /// // 创建不同的圆角
1099    /// let radius = BorderRadius::new(20.0, 10.0, 5.0, 15.0);
1100    ///
1101    /// let rect = Rect::new(50, 50, 300, 200);
1102    /// canvas.draw_custom_border_rect(rect, &border, &radius);
1103    /// ```
1104    pub fn draw_custom_border_rect(
1105        &mut self,
1106        rect: Rect,
1107        border: &crate::border::Border,
1108        radius: &crate::border::BorderRadius,
1109    ) {
1110        // 限制圆角半径在合理范围内
1111        let radius = radius.clamp(rect.width as f32, rect.height as f32);
1112
1113        // 如果所有圆角都是0,使用简化的直角矩形绘制
1114        if radius.is_zero() {
1115            self.draw_custom_border_rect_no_radius(rect, border);
1116            return;
1117        }
1118
1119        // 绘制四条边(考虑圆角)
1120        // 上边:从左上圆角结束到右上圆角开始
1121        if border.top.width > 0.0 {
1122            let mut paint = crate::Paint::stroke(border.top.color, border.top.width);
1123            paint.set_dash_style(border.top.dash_style.clone());
1124
1125            let start = Point::new(rect.x + radius.top_left as i32, rect.y);
1126            let end = Point::new(rect.x + rect.width as i32 - radius.top_right as i32, rect.y);
1127            self.draw_dashed_line(start, end, &paint);
1128        }
1129
1130        // 右边:从右上圆角结束到右下圆角开始
1131        if border.right.width > 0.0 {
1132            let mut paint = crate::Paint::stroke(border.right.color, border.right.width);
1133            paint.set_dash_style(border.right.dash_style.clone());
1134
1135            let start = Point::new(rect.x + rect.width as i32, rect.y + radius.top_right as i32);
1136            let end = Point::new(
1137                rect.x + rect.width as i32,
1138                rect.y + rect.height as i32 - radius.bottom_right as i32,
1139            );
1140            self.draw_dashed_line(start, end, &paint);
1141        }
1142
1143        // 下边:从右下圆角结束到左下圆角开始
1144        if border.bottom.width > 0.0 {
1145            let mut paint = crate::Paint::stroke(border.bottom.color, border.bottom.width);
1146            paint.set_dash_style(border.bottom.dash_style.clone());
1147
1148            let start = Point::new(
1149                rect.x + rect.width as i32 - radius.bottom_right as i32,
1150                rect.y + rect.height as i32,
1151            );
1152            let end = Point::new(
1153                rect.x + radius.bottom_left as i32,
1154                rect.y + rect.height as i32,
1155            );
1156            self.draw_dashed_line(start, end, &paint);
1157        }
1158
1159        // 左边:从左下圆角结束到左上圆角开始
1160        if border.left.width > 0.0 {
1161            let mut paint = crate::Paint::stroke(border.left.color, border.left.width);
1162            paint.set_dash_style(border.left.dash_style.clone());
1163
1164            let start = Point::new(
1165                rect.x,
1166                rect.y + rect.height as i32 - radius.bottom_left as i32,
1167            );
1168            let end = Point::new(rect.x, rect.y + radius.top_left as i32);
1169            self.draw_dashed_line(start, end, &paint);
1170        }
1171
1172        // 绘制四个圆角
1173        // 左上角 (180° 到 270°)
1174        if radius.top_left > 0.0 {
1175            // 使用上边和左边的平均样式绘制圆角
1176            let corner_border = self.blend_corner_style(&border.top, &border.left);
1177            let mut paint = crate::Paint::stroke(corner_border.color, corner_border.width);
1178            paint.set_dash_style(corner_border.dash_style);
1179
1180            self.draw_dashed_arc(
1181                Point::new(
1182                    rect.x + radius.top_left as i32,
1183                    rect.y + radius.top_left as i32,
1184                ),
1185                radius.top_left,
1186                180.0,
1187                270.0,
1188                &paint,
1189            );
1190        }
1191
1192        // 右上角 (270° 到 360°)
1193        if radius.top_right > 0.0 {
1194            let corner_border = self.blend_corner_style(&border.top, &border.right);
1195            let mut paint = crate::Paint::stroke(corner_border.color, corner_border.width);
1196            paint.set_dash_style(corner_border.dash_style);
1197
1198            self.draw_dashed_arc(
1199                Point::new(
1200                    rect.x + rect.width as i32 - radius.top_right as i32,
1201                    rect.y + radius.top_right as i32,
1202                ),
1203                radius.top_right,
1204                270.0,
1205                360.0,
1206                &paint,
1207            );
1208        }
1209
1210        // 右下角 (0° 到 90°)
1211        if radius.bottom_right > 0.0 {
1212            let corner_border = self.blend_corner_style(&border.right, &border.bottom);
1213            let mut paint = crate::Paint::stroke(corner_border.color, corner_border.width);
1214            paint.set_dash_style(corner_border.dash_style);
1215
1216            self.draw_dashed_arc(
1217                Point::new(
1218                    rect.x + rect.width as i32 - radius.bottom_right as i32,
1219                    rect.y + rect.height as i32 - radius.bottom_right as i32,
1220                ),
1221                radius.bottom_right,
1222                0.0,
1223                90.0,
1224                &paint,
1225            );
1226        }
1227
1228        // 左下角 (90° 到 180°)
1229        if radius.bottom_left > 0.0 {
1230            let corner_border = self.blend_corner_style(&border.bottom, &border.left);
1231            let mut paint = crate::Paint::stroke(corner_border.color, corner_border.width);
1232            paint.set_dash_style(corner_border.dash_style);
1233
1234            self.draw_dashed_arc(
1235                Point::new(
1236                    rect.x + radius.bottom_left as i32,
1237                    rect.y + rect.height as i32 - radius.bottom_left as i32,
1238                ),
1239                radius.bottom_left,
1240                90.0,
1241                180.0,
1242                &paint,
1243            );
1244        }
1245    }
1246
1247    /// 绘制无圆角的自定义边框矩形
1248    fn draw_custom_border_rect_no_radius(&mut self, rect: Rect, border: &crate::border::Border) {
1249        // 上边
1250        if border.top.width > 0.0 {
1251            let mut paint = crate::Paint::stroke(border.top.color, border.top.width);
1252            paint.set_dash_style(border.top.dash_style.clone());
1253            self.draw_dashed_line(
1254                Point::new(rect.x, rect.y),
1255                Point::new(rect.x + rect.width as i32, rect.y),
1256                &paint,
1257            );
1258        }
1259
1260        // 右边
1261        if border.right.width > 0.0 {
1262            let mut paint = crate::Paint::stroke(border.right.color, border.right.width);
1263            paint.set_dash_style(border.right.dash_style.clone());
1264            self.draw_dashed_line(
1265                Point::new(rect.x + rect.width as i32, rect.y),
1266                Point::new(rect.x + rect.width as i32, rect.y + rect.height as i32),
1267                &paint,
1268            );
1269        }
1270
1271        // 下边
1272        if border.bottom.width > 0.0 {
1273            let mut paint = crate::Paint::stroke(border.bottom.color, border.bottom.width);
1274            paint.set_dash_style(border.bottom.dash_style.clone());
1275            self.draw_dashed_line(
1276                Point::new(rect.x + rect.width as i32, rect.y + rect.height as i32),
1277                Point::new(rect.x, rect.y + rect.height as i32),
1278                &paint,
1279            );
1280        }
1281
1282        // 左边
1283        if border.left.width > 0.0 {
1284            let mut paint = crate::Paint::stroke(border.left.color, border.left.width);
1285            paint.set_dash_style(border.left.dash_style.clone());
1286            self.draw_dashed_line(
1287                Point::new(rect.x, rect.y + rect.height as i32),
1288                Point::new(rect.x, rect.y),
1289                &paint,
1290            );
1291        }
1292    }
1293
1294    /// 混合两条边的样式用于圆角(取平均值)
1295    fn blend_corner_style(
1296        &self,
1297        side1: &crate::border::BorderSide,
1298        side2: &crate::border::BorderSide,
1299    ) -> crate::border::BorderSide {
1300        // 如果其中一条边宽度为0,使用另一条
1301        if side1.width == 0.0 {
1302            return side2.clone();
1303        }
1304        if side2.width == 0.0 {
1305            return side1.clone();
1306        }
1307
1308        // 混合颜色(简单平均)
1309        let color = crate::Color::rgba(
1310            ((side1.color.r as u16 + side2.color.r as u16) / 2) as u8,
1311            ((side1.color.g as u16 + side2.color.g as u16) / 2) as u8,
1312            ((side1.color.b as u16 + side2.color.b as u16) / 2) as u8,
1313            ((side1.color.a as u16 + side2.color.a as u16) / 2) as u8,
1314        );
1315
1316        // 混合线宽(取平均)
1317        let width = (side1.width + side2.width) / 2.0;
1318
1319        // 虚线样式:优先使用第一条边的样式
1320        let dash_style = side1.dash_style.clone();
1321
1322        crate::border::BorderSide::new(color, width, dash_style)
1323    }
1324
1325    // ==================== 路径绘制方法 ====================
1326
1327    /// 绘制路径
1328    ///
1329    /// 根据 Paint 的样式绘制路径(填充或描边)
1330    ///
1331    /// # 参数
1332    ///
1333    /// * `path` - 要绘制的路径
1334    /// * `paint` - 绘制样式
1335    pub fn draw_path(&mut self, path: &Path, paint: &Paint) {
1336        // 应用当前变换矩阵
1337        let transformed_path = path.transform(&self.current_matrix);
1338
1339        match paint.style() {
1340            PaintStyle::Fill | PaintStyle::FillAndStroke => {
1341                self.fill_path(&transformed_path, paint);
1342            }
1343            PaintStyle::Stroke => {
1344                self.stroke_path(&transformed_path, paint);
1345            }
1346        }
1347    }
1348
1349    /// 填充路径
1350    fn fill_path(&mut self, path: &Path, paint: &Paint) {
1351        let color = paint.color().to_rgba();
1352
1353        // 获取路径的边界框
1354        if let Some(bounds) = path.bounds() {
1355            // 遍历边界框内的每个像素,判断是否在路径内
1356            for y in bounds.y..(bounds.y + bounds.height as i32) {
1357                for x in bounds.x..(bounds.x + bounds.width as i32) {
1358                    if path.contains(x as f32, y as f32) {
1359                        if x >= 0 && y >= 0 && x < self.width() as i32 && y < self.height() as i32 {
1360                            // 检查裁剪
1361                            if self.clip_stack.contains_point(x, y) {
1362                                self.surface.put_pixel(x as u32, y as u32, color);
1363                            }
1364                        }
1365                    }
1366                }
1367            }
1368        }
1369    }
1370
1371    /// 描边路径
1372    fn stroke_path(&mut self, path: &Path, paint: &Paint) {
1373        // 简化实现:将路径转换为线段序列并绘制
1374        let commands = path.commands();
1375        let mut current_point = None;
1376
1377        for cmd in commands {
1378            match cmd {
1379                crate::path::PathCommand::MoveTo(p) => {
1380                    current_point = Some(*p);
1381                }
1382                crate::path::PathCommand::LineTo(p) => {
1383                    if let Some(start) = current_point {
1384                        self.draw_line(
1385                            Point::new(start.x as i32, start.y as i32),
1386                            Point::new(p.x as i32, p.y as i32),
1387                            paint,
1388                        );
1389                    }
1390                    current_point = Some(*p);
1391                }
1392                crate::path::PathCommand::QuadTo { control, end } => {
1393                    if let Some(start) = current_point {
1394                        // 使用多段线近似二次贝塞尔曲线
1395                        self.draw_quad_bezier(start, *control, *end, paint);
1396                    }
1397                    current_point = Some(*end);
1398                }
1399                crate::path::PathCommand::CubicTo {
1400                    control1,
1401                    control2,
1402                    end,
1403                } => {
1404                    if let Some(start) = current_point {
1405                        // 使用多段线近似三次贝塞尔曲线
1406                        self.draw_cubic_bezier(start, *control1, *control2, *end, paint);
1407                    }
1408                    current_point = Some(*end);
1409                }
1410                crate::path::PathCommand::ArcTo { .. } => {
1411                    // 圆弧绘制的简化实现
1412                    // 在实际应用中需要更复杂的实现
1413                }
1414                crate::path::PathCommand::Close => {
1415                    // 闭合路径
1416                }
1417            }
1418        }
1419    }
1420
1421    /// 绘制二次贝塞尔曲线
1422    fn draw_quad_bezier(
1423        &mut self,
1424        start: crate::point::PointF,
1425        control: crate::point::PointF,
1426        end: crate::point::PointF,
1427        paint: &Paint,
1428    ) {
1429        let steps = 20;
1430        let mut prev = start;
1431
1432        for i in 1..=steps {
1433            let t = i as f32 / steps as f32;
1434            let t2 = t * t;
1435            let mt = 1.0 - t;
1436            let mt2 = mt * mt;
1437
1438            let x = mt2 * start.x + 2.0 * mt * t * control.x + t2 * end.x;
1439            let y = mt2 * start.y + 2.0 * mt * t * control.y + t2 * end.y;
1440
1441            let curr = crate::point::PointF { x, y };
1442            self.draw_line(
1443                Point::new(prev.x as i32, prev.y as i32),
1444                Point::new(curr.x as i32, curr.y as i32),
1445                paint,
1446            );
1447            prev = curr;
1448        }
1449    }
1450
1451    /// 绘制三次贝塞尔曲线
1452    fn draw_cubic_bezier(
1453        &mut self,
1454        start: crate::point::PointF,
1455        control1: crate::point::PointF,
1456        control2: crate::point::PointF,
1457        end: crate::point::PointF,
1458        paint: &Paint,
1459    ) {
1460        let steps = 30;
1461        let mut prev = start;
1462
1463        for i in 1..=steps {
1464            let t = i as f32 / steps as f32;
1465            let t2 = t * t;
1466            let t3 = t2 * t;
1467            let mt = 1.0 - t;
1468            let mt2 = mt * mt;
1469            let mt3 = mt2 * mt;
1470
1471            let x = mt3 * start.x
1472                + 3.0 * mt2 * t * control1.x
1473                + 3.0 * mt * t2 * control2.x
1474                + t3 * end.x;
1475            let y = mt3 * start.y
1476                + 3.0 * mt2 * t * control1.y
1477                + 3.0 * mt * t2 * control2.y
1478                + t3 * end.y;
1479
1480            let curr = crate::point::PointF { x, y };
1481            self.draw_line(
1482                Point::new(prev.x as i32, prev.y as i32),
1483                Point::new(curr.x as i32, curr.y as i32),
1484                paint,
1485            );
1486            prev = curr;
1487        }
1488    }
1489
1490    // ==================== 变换方法 ====================
1491
1492    /// 平移变换
1493    ///
1494    /// 将后续的绘制操作沿 x 和 y 方向平移
1495    ///
1496    /// # 参数
1497    ///
1498    /// * `dx` - x 方向的平移量
1499    /// * `dy` - y 方向的平移量
1500    pub fn translate(&mut self, dx: f32, dy: f32) {
1501        self.current_matrix = self.current_matrix.pre_translate(dx, dy);
1502    }
1503
1504    /// 缩放变换
1505    ///
1506    /// 将后续的绘制操作进行缩放
1507    ///
1508    /// # 参数
1509    ///
1510    /// * `sx` - x 方向的缩放因子
1511    /// * `sy` - y 方向的缩放因子
1512    pub fn scale(&mut self, sx: f32, sy: f32) {
1513        self.current_matrix = self.current_matrix.pre_scale(sx, sy);
1514    }
1515
1516    /// 旋转变换
1517    ///
1518    /// 将后续的绘制操作绕原点旋转指定角度
1519    ///
1520    /// # 参数
1521    ///
1522    /// * `degrees` - 旋转角度(度数)
1523    pub fn rotate(&mut self, degrees: f32) {
1524        self.current_matrix = self.current_matrix.pre_rotate(degrees);
1525    }
1526
1527    /// 绕指定点旋转
1528    ///
1529    /// # 参数
1530    ///
1531    /// * `degrees` - 旋转角度(度数)
1532    /// * `px` - 旋转中心的 x 坐标
1533    /// * `py` - 旋转中心的 y 坐标
1534    pub fn rotate_around(&mut self, degrees: f32, px: f32, py: f32) {
1535        self.translate(px, py);
1536        self.rotate(degrees);
1537        self.translate(-px, -py);
1538    }
1539
1540    /// 设置变换矩阵
1541    ///
1542    /// 直接设置当前的变换矩阵
1543    ///
1544    /// # 参数
1545    ///
1546    /// * `matrix` - 新的变换矩阵
1547    pub fn set_matrix(&mut self, matrix: &Matrix) {
1548        self.current_matrix = *matrix;
1549    }
1550
1551    /// 获取当前变换矩阵
1552    pub fn get_matrix(&self) -> &Matrix {
1553        &self.current_matrix
1554    }
1555
1556    /// 连接变换矩阵
1557    ///
1558    /// 将指定矩阵与当前矩阵相乘
1559    ///
1560    /// # 参数
1561    ///
1562    /// * `matrix` - 要连接的矩阵
1563    pub fn concat(&mut self, matrix: &Matrix) {
1564        self.current_matrix = self.current_matrix.post_concat(matrix);
1565    }
1566
1567    /// 重置变换矩阵为单位矩阵
1568    pub fn reset_matrix(&mut self) {
1569        self.current_matrix = Matrix::identity();
1570    }
1571
1572    // ==================== 状态保存和恢复 ====================
1573
1574    /// 保存当前的绘制状态
1575    ///
1576    /// 将当前的变换矩阵和裁剪区域压入状态栈
1577    pub fn save(&mut self) {
1578        let state = CanvasState {
1579            matrix: self.current_matrix,
1580            clip_rect: self.clip_stack.get_bounds(),
1581        };
1582        self.state_stack.push(state);
1583        self.clip_stack.save();
1584    }
1585
1586    /// 恢复之前保存的绘制状态
1587    ///
1588    /// 从状态栈中弹出并恢复变换矩阵和裁剪区域
1589    pub fn restore(&mut self) {
1590        if let Some(state) = self.state_stack.pop() {
1591            self.current_matrix = state.matrix;
1592            self.clip_stack.restore();
1593        }
1594    }
1595
1596    /// 获取当前保存的状态层数
1597    pub fn get_save_count(&self) -> usize {
1598        self.state_stack.len()
1599    }
1600
1601    /// 恢复到指定的保存层级
1602    ///
1603    /// # 参数
1604    ///
1605    /// * `count` - 目标层级数
1606    pub fn restore_to_count(&mut self, count: usize) {
1607        while self.state_stack.len() > count {
1608            self.restore();
1609        }
1610    }
1611
1612    // ==================== 裁剪方法 ====================
1613
1614    /// 矩形裁剪
1615    ///
1616    /// 将绘制区域限制在指定的矩形内
1617    ///
1618    /// # 参数
1619    ///
1620    /// * `rect` - 裁剪矩形
1621    /// * `op` - 裁剪操作(相交或差集)
1622    pub fn clip_rect(&mut self, rect: Rect, op: ClipOp) {
1623        // 应用当前变换到裁剪矩形
1624        let transformed_rect = self.transform_rect(rect);
1625        self.clip_stack.clip_rect(transformed_rect, op);
1626    }
1627
1628    /// 路径裁剪
1629    ///
1630    /// 将绘制区域限制在指定的路径内
1631    ///
1632    /// # 参数
1633    ///
1634    /// * `path` - 裁剪路径
1635    /// * `op` - 裁剪操作(相交或差集)
1636    pub fn clip_path(&mut self, path: &Path, op: ClipOp) {
1637        // 应用当前变换到裁剪路径
1638        let transformed_path = path.transform(&self.current_matrix);
1639        self.clip_stack.clip_path(transformed_path, op);
1640    }
1641
1642    /// 获取当前裁剪区域的边界
1643    pub fn get_clip_bounds(&self) -> Option<Rect> {
1644        self.clip_stack.get_bounds()
1645    }
1646
1647    /// 检查点是否在裁剪区域内
1648    pub fn is_clipped(&self, x: i32, y: i32) -> bool {
1649        !self.clip_stack.contains_point(x, y)
1650    }
1651
1652    // ==================== 辅助方法 ====================
1653
1654    /// 应用变换到矩形
1655    fn transform_rect(&self, rect: Rect) -> Rect {
1656        let (x1, y1) = self.current_matrix.map_point(rect.x as f32, rect.y as f32);
1657        let (x2, y2) = self.current_matrix.map_point(
1658            (rect.x + rect.width as i32) as f32,
1659            (rect.y + rect.height as i32) as f32,
1660        );
1661
1662        Rect::new(
1663            x1 as i32,
1664            y1 as i32,
1665            (x2 - x1).abs() as u32,
1666            (y2 - y1).abs() as u32,
1667        )
1668    }
1669}