1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use crate::drawing::backend::{BackendCoord, BackendStyle, DrawingErrorKind};
use crate::drawing::DrawingBackend;
use crate::style::Color;
pub(crate) fn draw_circle<B: DrawingBackend, S: BackendStyle>(
b: &mut B,
center: BackendCoord,
radius: u32,
style: &S,
fill: bool,
) -> Result<(), DrawingErrorKind<B::ErrorType>> {
if style.as_color().alpha() == 0.0 {
return Ok(());
}
if !fill && style.stroke_width() != 1 {
}
let min = (f64::from(radius) * (1.0 - (2f64).sqrt() / 2.0)).ceil() as i32;
let max = (f64::from(radius) * (1.0 + (2f64).sqrt() / 2.0)).floor() as i32;
let range = min..=max;
let (up, down) = (
range.start() + center.1 - radius as i32,
range.end() + center.1 - radius as i32,
);
for dy in range {
let dy = dy - radius as i32;
let y = center.1 + dy;
let lx = (f64::from(radius) * f64::from(radius)
- (f64::from(dy) * f64::from(dy)).max(1e-5))
.sqrt();
let left = center.0 - lx.floor() as i32;
let right = center.0 + lx.floor() as i32;
let v = lx - lx.floor();
let x = center.0 + dy;
let top = center.1 - lx.floor() as i32;
let bottom = center.1 + lx.floor() as i32;
if fill {
b.draw_line((left, y), (right, y), &style.as_color())?;
b.draw_line((x, top), (x, up), &style.as_color())?;
b.draw_line((x, down), (x, bottom), &style.as_color())?;
} else {
b.draw_pixel((left, y), &style.as_color().mix(1.0 - v))?;
b.draw_pixel((right, y), &style.as_color().mix(1.0 - v))?;
b.draw_pixel((x, top), &style.as_color().mix(1.0 - v))?;
b.draw_pixel((x, bottom), &style.as_color().mix(1.0 - v))?;
}
b.draw_pixel((left - 1, y), &style.as_color().mix(v))?;
b.draw_pixel((right + 1, y), &style.as_color().mix(v))?;
b.draw_pixel((x, top - 1), &style.as_color().mix(v))?;
b.draw_pixel((x, bottom + 1), &style.as_color().mix(v))?;
}
Ok(())
}