Implement `Path2D::arc_to`.
This commit is contained in:
parent
f20d41800c
commit
44167beff5
|
@ -14,6 +14,7 @@ use font_kit::family_name::FamilyName;
|
||||||
use font_kit::hinting::HintingOptions;
|
use font_kit::hinting::HintingOptions;
|
||||||
use font_kit::properties::Properties;
|
use font_kit::properties::Properties;
|
||||||
use font_kit::source::SystemSource;
|
use font_kit::source::SystemSource;
|
||||||
|
use pathfinder_geometry::basic::line_segment::LineSegmentF;
|
||||||
use pathfinder_geometry::basic::point::Point2DF;
|
use pathfinder_geometry::basic::point::Point2DF;
|
||||||
use pathfinder_geometry::basic::rect::RectF;
|
use pathfinder_geometry::basic::rect::RectF;
|
||||||
use pathfinder_geometry::basic::transform2d::Transform2DF;
|
use pathfinder_geometry::basic::transform2d::Transform2DF;
|
||||||
|
@ -341,6 +342,24 @@ impl Path2D {
|
||||||
self.current_contour.push_arc(&transform, start_angle, end_angle);
|
self.current_contour.push_arc(&transform, start_angle, end_angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn arc_to(&mut self, ctrl: Point2DF, to: Point2DF, radius: f32) {
|
||||||
|
// FIXME(pcwalton): What should we do if there's no initial point?
|
||||||
|
let from = self.current_contour.last_position().unwrap_or_default();
|
||||||
|
let (v0, v1) = (from - ctrl, to - ctrl);
|
||||||
|
let (vu0, vu1) = (v0.normalize(), v1.normalize());
|
||||||
|
let hypot = radius / f32::sqrt(0.5 * (1.0 - vu0.dot(vu1)));
|
||||||
|
let bisector = vu0 + vu1;
|
||||||
|
let center = ctrl + bisector.scale(hypot / bisector.length());
|
||||||
|
|
||||||
|
let mut transform = Transform2DF::from_scale(Point2DF::splat(radius));
|
||||||
|
transform = transform.post_mul(&Transform2DF::from_translation(center));
|
||||||
|
|
||||||
|
let chord = LineSegmentF::new(vu0.yx().scale_xy(Point2DF::new(-1.0, 1.0)),
|
||||||
|
vu1.yx().scale_xy(Point2DF::new(1.0, -1.0)));
|
||||||
|
self.current_contour.push_arc_from_unit_chord(&transform, chord);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rect(&mut self, rect: RectF) {
|
pub fn rect(&mut self, rect: RectF) {
|
||||||
self.flush_current_contour();
|
self.flush_current_contour();
|
||||||
self.current_contour.push_endpoint(rect.origin());
|
self.current_contour.push_endpoint(rect.origin());
|
||||||
|
|
|
@ -269,13 +269,13 @@ impl Contour {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn position_of_last(&self, index: u32) -> Point2DF {
|
pub fn last_position(&self) -> Option<Point2DF> {
|
||||||
self.points[self.points.len() - index as usize]
|
self.points.last().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn last_position(&self) -> Option<Point2DF> {
|
pub(crate) fn position_of_last(&self, index: u32) -> Point2DF {
|
||||||
self.points.last().cloned()
|
self.points[self.points.len() - index as usize]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -409,7 +409,7 @@ impl Contour {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector = sweep_vector.rotate_by(vector);
|
vector = vector.rotate_by(sweep_vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
const EPSILON: f32 = 0.001;
|
const EPSILON: f32 = 0.001;
|
||||||
|
|
Loading…
Reference in New Issue