Skip to content

Commit 87dc682

Browse files
committed
Bug fix: line rasterizer may overflow the image buffer
1 parent c69b23b commit 87dc682

File tree

3 files changed

+22
-3
lines changed

3 files changed

+22
-3
lines changed

src/drawing/backend_impl/canvas.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ impl DrawingBackend for CanvasBackend {
112112
return Ok(());
113113
}
114114

115-
self.context.set_stroke_style(&make_canvas_color(style.as_color()));
115+
self.context
116+
.set_stroke_style(&make_canvas_color(style.as_color()));
116117
self.context.set_line_width(style.stroke_width() as f64);
117118
self.context.begin_path();
118119
self.context.move_to(f64::from(from.0), f64::from(from.1));

src/drawing/rasterizer/line.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ pub fn draw_line<DB: DrawingBackend, S: BackendStyle>(
7575
(from, to)
7676
};
7777

78+
let mut size_limit = back.get_size();
79+
80+
if steep {
81+
size_limit = (size_limit.1, size_limit.0);
82+
}
83+
7884
let grad = f64::from(to.1 - from.1) / f64::from(to.0 - from.0);
7985

8086
let mut put_pixel = |(x, y): BackendCoord, b: f64| {
@@ -87,12 +93,24 @@ pub fn draw_line<DB: DrawingBackend, S: BackendStyle>(
8793

8894
let mut y = f64::from(from.1);
8995

90-
for x in from.0..=to.0 {
96+
let y_step_limit = (f64::from(to.1.min(size_limit.1 as i32 - 1) - from.1) / grad).ceil() as i32;
97+
98+
for x in from.0..=to.0.min(size_limit.0 as i32 - 2).min(from.0 + y_step_limit) {
9199
check_result!(put_pixel((x, y as i32), 1.0 + y.floor() - y));
92100
check_result!(put_pixel((x, y as i32 + 1), y - y.floor()));
93101

94102
y += grad;
95103
}
96104

105+
if to.0 >= (size_limit.0 as i32) - 1 && y < f64::from(to.1) {
106+
let x = size_limit.0 as i32 - 1;
107+
if 1.0 + y.floor() - y > 1e-5 {
108+
check_result!(put_pixel((x, y as i32), 1.0 + y.floor() - y));
109+
}
110+
if y - y.floor() > 1e-5 && y + 1.0 < f64::from(to.1) {
111+
check_result!(put_pixel((x, y as i32 + 1), y - y.floor()));
112+
}
113+
}
114+
97115
Ok(())
98116
}

src/drawing/rasterizer/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fn compute_polygon_vertex(triple: &[BackendCoord; 3], d: f64) -> BackendCoord {
4040
let b1 = -b_t.1;
4141
let c1 = b_p.1 - a_p.1;
4242

43-
// This is the coner case that
43+
// This is the coner case that
4444
if (a0 * b1 - a1 * b0).abs() < 1e-10 {
4545
return (a_p.0 as i32, a_p.1 as i32);
4646
}

0 commit comments

Comments
 (0)