Desktop: Snap overlays to physical instead of logical pixels (#3493)
WIP
This commit is contained in:
parent
c7e3d01e2b
commit
9c56c852ca
|
|
@ -491,11 +491,13 @@ impl OverlayContextInternal {
|
|||
|
||||
let mut path = BezPath::new();
|
||||
if let Some(first) = polygon.last() {
|
||||
path.move_to(kurbo::Point::new(first.x.round() - 0.5, first.y.round() - 0.5));
|
||||
let p = self.snap_to_physical_pixel_center(*first);
|
||||
path.move_to(kurbo::Point::new(p.x, p.y));
|
||||
}
|
||||
|
||||
for point in polygon {
|
||||
path.line_to(kurbo::Point::new(point.x.round() - 0.5, point.y.round() - 0.5));
|
||||
let p = self.snap_to_physical_pixel_center(*point);
|
||||
path.line_to(kurbo::Point::new(p.x, p.y));
|
||||
}
|
||||
path.close_path();
|
||||
|
||||
|
|
@ -522,8 +524,8 @@ impl OverlayContextInternal {
|
|||
fn dashed_line(&mut self, start: DVec2, end: DVec2, color: Option<&str>, thickness: Option<f64>, dash_width: Option<f64>, dash_gap_width: Option<f64>, dash_offset: Option<f64>) {
|
||||
let transform = self.get_transform();
|
||||
|
||||
let start = start.round() - DVec2::splat(0.5);
|
||||
let end = end.round() - DVec2::splat(0.5);
|
||||
let start = self.snap_to_physical_pixel_center(start);
|
||||
let end = self.snap_to_physical_pixel_center(end);
|
||||
|
||||
let mut path = BezPath::new();
|
||||
path.move_to(kurbo::Point::new(start.x, start.y));
|
||||
|
|
@ -541,7 +543,7 @@ impl OverlayContextInternal {
|
|||
|
||||
fn manipulator_handle(&mut self, position: DVec2, selected: bool, color: Option<&str>) {
|
||||
let transform = self.get_transform();
|
||||
let position = position.round() - DVec2::splat(0.5);
|
||||
let position = self.snap_to_physical_pixel_center(position);
|
||||
|
||||
let circle = kurbo::Circle::new((position.x, position.y), MANIPULATOR_GROUP_MARKER_SIZE / 2.);
|
||||
|
||||
|
|
@ -554,8 +556,7 @@ impl OverlayContextInternal {
|
|||
|
||||
fn hover_manipulator_handle(&mut self, position: DVec2, selected: bool) {
|
||||
let transform = self.get_transform();
|
||||
|
||||
let position = position.round() - DVec2::splat(0.5);
|
||||
let position = self.snap_to_physical_pixel_center(position);
|
||||
|
||||
let circle = kurbo::Circle::new((position.x, position.y), (MANIPULATOR_GROUP_MARKER_SIZE + 2.) / 2.);
|
||||
|
||||
|
|
@ -605,7 +606,7 @@ impl OverlayContextInternal {
|
|||
let color_fill = color_fill.unwrap_or(COLOR_OVERLAY_WHITE);
|
||||
let color_stroke = color_stroke.unwrap_or(COLOR_OVERLAY_BLUE);
|
||||
|
||||
let position = position.round() - DVec2::splat(0.5);
|
||||
let position = self.snap_to_physical_pixel_center(position);
|
||||
let corner = position - DVec2::splat(size) / 2.;
|
||||
|
||||
let transform = self.get_transform();
|
||||
|
|
@ -620,7 +621,7 @@ impl OverlayContextInternal {
|
|||
let size = 1.;
|
||||
let color_fill = color.unwrap_or(COLOR_OVERLAY_WHITE);
|
||||
|
||||
let position = position.round() - DVec2::splat(0.5);
|
||||
let position = self.snap_to_physical_pixel_center(position);
|
||||
let corner = position - DVec2::splat(size) / 2.;
|
||||
|
||||
let transform = self.get_transform();
|
||||
|
|
@ -632,7 +633,7 @@ impl OverlayContextInternal {
|
|||
fn circle(&mut self, position: DVec2, radius: f64, color_fill: Option<&str>, color_stroke: Option<&str>) {
|
||||
let color_fill = color_fill.unwrap_or(COLOR_OVERLAY_WHITE);
|
||||
let color_stroke = color_stroke.unwrap_or(COLOR_OVERLAY_BLUE);
|
||||
let position = position.round();
|
||||
let position = self.snap_to_physical_pixel(position);
|
||||
|
||||
let transform = self.get_transform();
|
||||
let circle = kurbo::Circle::new((position.x, position.y), radius);
|
||||
|
|
@ -708,7 +709,7 @@ impl OverlayContextInternal {
|
|||
self.draw_arc(pivot, arc_radius, offset_angle, (angle) % TAU + offset_angle);
|
||||
}
|
||||
|
||||
fn draw_scale(&mut self, start: DVec2, scale: f64, radius: f64, text: &str) {
|
||||
pub fn draw_scale(&mut self, start: DVec2, scale: f64, radius: f64, text: &str) {
|
||||
let sign = scale.signum();
|
||||
let mut fill_color = Color::from_rgb_str(COLOR_OVERLAY_WHITE.strip_prefix('#').unwrap()).unwrap().with_alpha(0.05).to_rgba_hex_srgb();
|
||||
fill_color.insert(0, '#');
|
||||
|
|
@ -739,7 +740,7 @@ impl OverlayContextInternal {
|
|||
let Some(show_hover_ring) = show_compass_with_hover_ring else { return };
|
||||
|
||||
let transform = self.get_transform();
|
||||
let center = compass_center.round() - DVec2::splat(0.5);
|
||||
let center = self.snap_to_physical_pixel_center(compass_center);
|
||||
|
||||
// Hover ring
|
||||
if show_hover_ring {
|
||||
|
|
@ -784,7 +785,7 @@ impl OverlayContextInternal {
|
|||
|
||||
fn pivot(&mut self, position: DVec2, angle: f64) {
|
||||
let uv = DVec2::from_angle(angle);
|
||||
let (x, y) = (position.round() - DVec2::splat(0.5)).into();
|
||||
let (x, y) = self.snap_to_physical_pixel_center(position).into();
|
||||
|
||||
let transform = self.get_transform();
|
||||
|
||||
|
|
@ -814,7 +815,7 @@ impl OverlayContextInternal {
|
|||
}
|
||||
|
||||
fn dowel_pin(&mut self, position: DVec2, angle: f64, color: Option<&str>) {
|
||||
let (x, y) = (position.round() - DVec2::splat(0.5)).into();
|
||||
let (x, y) = self.snap_to_physical_pixel_center(position).into();
|
||||
let color = color.unwrap_or(COLOR_OVERLAY_YELLOW_DULL);
|
||||
|
||||
let transform = self.get_transform();
|
||||
|
|
@ -921,29 +922,30 @@ impl OverlayContextInternal {
|
|||
};
|
||||
|
||||
let start_point = transform.transform_point2(point_to_dvec2(first.start()));
|
||||
let start_point = self.snap_to_physical_pixel(start_point);
|
||||
path.move_to(kurbo::Point::new(start_point.x, start_point.y));
|
||||
|
||||
for curve in curves {
|
||||
match curve {
|
||||
PathSeg::Line(line) => {
|
||||
let a = transform.transform_point2(point_to_dvec2(line.p1));
|
||||
let a = a.round() - DVec2::splat(0.5);
|
||||
let a = self.snap_to_physical_pixel_center(a);
|
||||
path.line_to(kurbo::Point::new(a.x, a.y));
|
||||
}
|
||||
PathSeg::Quad(quad_bez) => {
|
||||
let a = transform.transform_point2(point_to_dvec2(quad_bez.p1));
|
||||
let b = transform.transform_point2(point_to_dvec2(quad_bez.p2));
|
||||
let a = a.round() - DVec2::splat(0.5);
|
||||
let b = b.round() - DVec2::splat(0.5);
|
||||
let a = self.snap_to_physical_pixel_center(a);
|
||||
let b = self.snap_to_physical_pixel_center(b);
|
||||
path.quad_to(kurbo::Point::new(a.x, a.y), kurbo::Point::new(b.x, b.y));
|
||||
}
|
||||
PathSeg::Cubic(cubic_bez) => {
|
||||
let a = transform.transform_point2(point_to_dvec2(cubic_bez.p1));
|
||||
let b = transform.transform_point2(point_to_dvec2(cubic_bez.p2));
|
||||
let c = transform.transform_point2(point_to_dvec2(cubic_bez.p3));
|
||||
let a = a.round() - DVec2::splat(0.5);
|
||||
let b = b.round() - DVec2::splat(0.5);
|
||||
let c = c.round() - DVec2::splat(0.5);
|
||||
let a = self.snap_to_physical_pixel_center(a);
|
||||
let b = self.snap_to_physical_pixel_center(b);
|
||||
let c = self.snap_to_physical_pixel_center(c);
|
||||
path.curve_to(kurbo::Point::new(a.x, a.y), kurbo::Point::new(b.x, b.y), kurbo::Point::new(c.x, c.y));
|
||||
}
|
||||
}
|
||||
|
|
@ -1145,4 +1147,20 @@ impl OverlayContextInternal {
|
|||
self.line(quad.bottom_left(), quad.bottom_right(), None, None);
|
||||
}
|
||||
}
|
||||
|
||||
fn snap_to_physical_pixel(&self, p: DVec2) -> DVec2 {
|
||||
let s = self.viewport.scale();
|
||||
if !s.is_finite() || s <= 0.0 {
|
||||
return p.round();
|
||||
}
|
||||
(p * s).round() / s
|
||||
}
|
||||
|
||||
fn snap_to_physical_pixel_center(&self, p: DVec2) -> DVec2 {
|
||||
let s = self.viewport.scale();
|
||||
if !s.is_finite() || s <= 0.0 {
|
||||
return p.round() - DVec2::splat(0.5);
|
||||
}
|
||||
self.snap_to_physical_pixel(p) - DVec2::splat(0.5 / s)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue