Add arc building methods and switch the Moiré demo to use them.

Also, stop taking points by reference in many methods, for consistency.
This commit is contained in:
Patrick Walton 2019-05-13 12:17:49 -07:00
parent 55be787ffd
commit f24d93819b
14 changed files with 157 additions and 97 deletions

1
Cargo.lock generated
View File

@ -180,6 +180,7 @@ dependencies = [
"pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0",
"pathfinder_renderer 0.1.0",
"pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@ -97,7 +97,7 @@ impl CanvasRenderingContext2D {
drop(self.scene.push_text(string,
&TextStyle { size: self.current_state.font_size },
&self.current_state.font_collection,
&Transform2DF32::from_translation(&position),
&Transform2DF32::from_translation(position),
TextRenderMode::Fill,
HintingOptions::None,
paint_id));
@ -109,7 +109,7 @@ impl CanvasRenderingContext2D {
drop(self.scene.push_text(string,
&TextStyle { size: self.current_state.font_size },
&self.current_state.font_collection,
&Transform2DF32::from_translation(&position),
&Transform2DF32::from_translation(position),
TextRenderMode::Stroke(self.current_state.line_width),
HintingOptions::None,
paint_id));
@ -196,7 +196,7 @@ pub struct Path2D {
current_contour: Contour,
}
// TODO(pcwalton): `arc`, `ellipse`
// TODO(pcwalton): `ellipse`
impl Path2D {
#[inline]
pub fn new() -> Path2D {
@ -230,6 +230,11 @@ impl Path2D {
self.current_contour.push_cubic(ctrl0, ctrl1, to);
}
#[inline]
pub fn arc(&mut self, center: Point2DF32, radius: f32, start_angle: f32, end_angle: f32) {
self.current_contour.push_arc(center, radius, start_angle, end_angle);
}
pub fn rect(&mut self, rect: RectF32) {
self.flush_current_contour();
self.current_contour.push_endpoint(rect.origin());

View File

@ -6,6 +6,7 @@ edition = "2018"
[dependencies]
gl = "0.6"
pretty_env_logger = "0.3"
sdl2 = "0.32"
sdl2-sys = "0.32"

View File

@ -21,6 +21,7 @@ use pathfinder_renderer::options::RenderOptions;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;
use std::f32::consts::PI;
use std::f32;
const VELOCITY: f32 = 0.02;
@ -36,6 +37,8 @@ const CIRCLE_THICKNESS: f32 = 16.0;
const COLOR_CYCLE_SPEED: f32 = 0.0025;
fn main() {
pretty_env_logger::init();
// Set up SDL2.
let sdl_context = sdl2::init().unwrap();
let video = sdl_context.video().unwrap();
@ -150,27 +153,14 @@ impl MoireRenderer {
}
fn draw_circles(&self, canvas: &mut CanvasRenderingContext2D, center: Point2DF32) {
let center = center.scale(self.device_pixel_ratio);
for index in 0..CIRCLE_COUNT {
let radius = (index + 1) as f32 * CIRCLE_SPACING * self.device_pixel_ratio;
let mut path = Path2D::new();
self.add_circle_subpath(&mut path,
center.scale(self.device_pixel_ratio),
index as f32 * CIRCLE_SPACING * self.device_pixel_ratio);
path.arc(center, radius, 0.0, PI * 2.0);
canvas.stroke_path(path);
}
}
fn add_circle_subpath(&self, path: &mut Path2D, center: Point2DF32, radius: f32) {
path.move_to(center + Point2DF32::new(0.0, -radius));
path.quadratic_curve_to(center + Point2DF32::new(radius, -radius),
center + Point2DF32::new(radius, 0.0));
path.quadratic_curve_to(center + Point2DF32::new(radius, radius),
center + Point2DF32::new(0.0, radius));
path.quadratic_curve_to(center + Point2DF32::new(-radius, radius),
center + Point2DF32::new(-radius, 0.0));
path.quadratic_curve_to(center + Point2DF32::new(-radius, -radius),
center + Point2DF32::new(0.0, -radius));
path.close_path();
}
}
struct ColorGradient([ColorF; 5]);

View File

@ -20,7 +20,7 @@ pub struct LineSegmentF32(pub F32x4);
impl LineSegmentF32 {
#[inline]
pub fn new(from: &Point2DF32, to: &Point2DF32) -> LineSegmentF32 {
pub fn new(from: Point2DF32, to: Point2DF32) -> LineSegmentF32 {
LineSegmentF32(from.0.concat_xy_xy(to.0))
}

View File

@ -10,6 +10,7 @@
//! 2D affine transforms.
use crate::basic::line_segment::LineSegmentF32;
use crate::basic::point::Point2DF32;
use crate::basic::rect::RectF32;
use crate::basic::transform3d::Transform3DF32;
@ -24,13 +25,13 @@ pub struct Matrix2x2F32(pub F32x4);
impl Default for Matrix2x2F32 {
#[inline]
fn default() -> Matrix2x2F32 {
Self::from_scale(&Point2DF32::splat(1.0))
Self::from_scale(Point2DF32::splat(1.0))
}
}
impl Matrix2x2F32 {
#[inline]
pub fn from_scale(scale: &Point2DF32) -> Matrix2x2F32 {
pub fn from_scale(scale: Point2DF32) -> Matrix2x2F32 {
Matrix2x2F32(F32x4::new(scale.x(), 0.0, 0.0, scale.y()))
}
@ -66,7 +67,7 @@ impl Matrix2x2F32 {
}
#[inline]
pub fn transform_point(&self, point: &Point2DF32) -> Point2DF32 {
pub fn transform_point(&self, point: Point2DF32) -> Point2DF32 {
let halves = self.0 * point.0.xxyy();
Point2DF32(halves + halves.zwzw())
}
@ -118,13 +119,13 @@ pub struct Transform2DF32 {
impl Default for Transform2DF32 {
#[inline]
fn default() -> Transform2DF32 {
Self::from_scale(&Point2DF32::splat(1.0))
Self::from_scale(Point2DF32::splat(1.0))
}
}
impl Transform2DF32 {
#[inline]
pub fn from_scale(scale: &Point2DF32) -> Transform2DF32 {
pub fn from_scale(scale: Point2DF32) -> Transform2DF32 {
Transform2DF32 {
matrix: Matrix2x2F32::from_scale(scale),
vector: Point2DF32::default(),
@ -140,11 +141,8 @@ impl Transform2DF32 {
}
#[inline]
pub fn from_translation(vector: &Point2DF32) -> Transform2DF32 {
Transform2DF32 {
matrix: Matrix2x2F32::default(),
vector: *vector,
}
pub fn from_translation(vector: Point2DF32) -> Transform2DF32 {
Transform2DF32 { matrix: Matrix2x2F32::default(), vector }
}
#[inline]
@ -154,10 +152,8 @@ impl Transform2DF32 {
translation: Point2DF32,
) -> Transform2DF32 {
let rotation = Transform2DF32::from_rotation(theta);
let translation = Transform2DF32::from_translation(&translation);
Transform2DF32::from_scale(&scale)
.post_mul(&rotation)
.post_mul(&translation)
let translation = Transform2DF32::from_translation(translation);
Transform2DF32::from_scale(scale).post_mul(&rotation).post_mul(&translation)
}
#[inline]
@ -169,16 +165,22 @@ impl Transform2DF32 {
}
#[inline]
pub fn transform_point(&self, point: &Point2DF32) -> Point2DF32 {
pub fn transform_point(&self, point: Point2DF32) -> Point2DF32 {
self.matrix.transform_point(point) + self.vector
}
#[inline]
pub fn transform_line_segment(&self, line_segment: &LineSegmentF32) -> LineSegmentF32 {
LineSegmentF32::new(self.transform_point(line_segment.from()),
self.transform_point(line_segment.to()))
}
#[inline]
pub fn transform_rect(&self, rect: &RectF32) -> RectF32 {
let upper_left = self.transform_point(&rect.origin());
let upper_right = self.transform_point(&rect.upper_right());
let lower_left = self.transform_point(&rect.lower_left());
let lower_right = self.transform_point(&rect.lower_right());
let upper_left = self.transform_point(rect.origin());
let upper_right = self.transform_point(rect.upper_right());
let lower_left = self.transform_point(rect.lower_left());
let lower_right = self.transform_point(rect.lower_right());
let min_point = upper_left.min(upper_right).min(lower_left).min(lower_right);
let max_point = upper_left.max(upper_right).max(lower_left).max(lower_right);
RectF32::from_points(min_point, max_point)
@ -187,7 +189,7 @@ impl Transform2DF32 {
#[inline]
pub fn post_mul(&self, other: &Transform2DF32) -> Transform2DF32 {
let matrix = self.matrix.post_mul(&other.matrix);
let vector = other.transform_point(&self.vector);
let vector = other.transform_point(self.vector);
Transform2DF32 { matrix, vector }
}
@ -243,7 +245,7 @@ impl Transform2DF32 {
#[inline]
pub fn post_translate(&self, vector: Point2DF32) -> Transform2DF32 {
self.post_mul(&Transform2DF32::from_translation(&vector))
self.post_mul(&Transform2DF32::from_translation(vector))
}
#[inline]
@ -253,7 +255,7 @@ impl Transform2DF32 {
#[inline]
pub fn post_scale(&self, scale: Point2DF32) -> Transform2DF32 {
self.post_mul(&Transform2DF32::from_scale(&scale))
self.post_mul(&Transform2DF32::from_scale(scale))
}
/// Returns the translation part of this matrix.
@ -303,18 +305,18 @@ where
if !segment.is_none() {
segment
.baseline
.set_from(&self.transform.transform_point(&segment.baseline.from()));
.set_from(&self.transform.transform_point(segment.baseline.from()));
segment
.baseline
.set_to(&self.transform.transform_point(&segment.baseline.to()));
.set_to(&self.transform.transform_point(segment.baseline.to()));
if !segment.is_line() {
segment
.ctrl
.set_from(&self.transform.transform_point(&segment.ctrl.from()));
.set_from(&self.transform.transform_point(segment.ctrl.from()));
if !segment.is_quadratic() {
segment
.ctrl
.set_to(&self.transform.transform_point(&segment.ctrl.to()));
.set_to(&self.transform.transform_point(segment.ctrl.to()));
}
}
}

View File

@ -325,7 +325,7 @@ impl ContourPolygonClipper {
Some(prev) => *prev,
};
for &next in &clip_polygon {
self.clip_against(Edge(LineSegmentF32::new(&prev, &next)));
self.clip_against(Edge(LineSegmentF32::new(prev, next)));
prev = next;
}

View File

@ -19,6 +19,7 @@ use crate::clip::{self, ContourPolygonClipper, ContourRectClipper};
use crate::dilation::ContourDilator;
use crate::orientation::Orientation;
use crate::segment::{Segment, SegmentFlags, SegmentKind};
use std::f32::consts::FRAC_PI_2;
use std::fmt::{self, Debug, Formatter};
use std::mem;
@ -292,7 +293,10 @@ impl Contour {
// TODO(pcwalton): SIMD.
#[inline]
pub(crate) fn push_point(&mut self, point: Point2DF32, flags: PointFlags, update_bounds: bool) {
pub(crate) fn push_point(&mut self,
point: Point2DF32,
flags: PointFlags,
update_bounds: bool) {
debug_assert!(!point.x().is_nan() && !point.y().is_nan());
if update_bounds {
@ -354,6 +358,37 @@ impl Contour {
self.push_point(segment.baseline.to(), PointFlags::empty(), update_bounds);
}
pub fn push_arc(&mut self, center: Point2DF32, radius: f32, start_angle: f32, end_angle: f32) {
let scale = Transform2DF32::from_scale(Point2DF32::splat(radius));
let translation = Transform2DF32::from_translation(center);
let (mut angle, mut first_segment) = (start_angle, true);
while angle < end_angle {
let sweep_angle = f32::min(FRAC_PI_2, end_angle - angle);
let mut segment = Segment::arc(sweep_angle);
let rotation = Transform2DF32::from_rotation(angle);
segment = segment.transform(&scale.post_mul(&rotation).post_mul(&translation));
/*
println!("angle={} start_angle={} end_angle={} sweep_angle={} segment={:?}",
angle,
start_angle,
end_angle,
sweep_angle,
segment);
*/
if first_segment {
self.push_full_segment(&segment, true);
first_segment = false;
} else {
self.push_segment(segment, true);
}
angle += sweep_angle;
}
}
#[inline]
pub fn segment_after(&self, point_index: u32) -> Segment {
debug_assert!(self.point_is_endpoint(point_index));
@ -388,8 +423,8 @@ impl Contour {
pub fn hull_segment_after(&self, prev_point_index: u32) -> LineSegmentF32 {
let next_point_index = self.next_point_index_of(prev_point_index);
LineSegmentF32::new(
&self.points[prev_point_index as usize],
&self.points[next_point_index as usize],
self.points[prev_point_index as usize],
self.points[next_point_index as usize],
)
}
@ -455,7 +490,7 @@ impl Contour {
pub fn transform(&mut self, transform: &Transform2DF32) {
for (point_index, point) in self.points.iter_mut().enumerate() {
*point = transform.transform_point(point);
*point = transform.transform_point(*point);
union_rect(&mut self.bounds, *point, point_index == 0);
}
}
@ -522,8 +557,8 @@ impl Contour {
point_index
};
let baseline = LineSegmentF32::new(
&contour.points[last_endpoint_index as usize],
&contour.points[position_index as usize],
contour.points[last_endpoint_index as usize],
contour.points[position_index as usize],
);
let point_count = point_index - last_endpoint_index + 1;
if point_count == 3 {
@ -531,13 +566,13 @@ impl Contour {
let ctrl_position = &contour.points[ctrl_point_index];
handle_cubic(
self,
Segment::quadratic(&baseline, &ctrl_position).to_cubic(),
Segment::quadratic(&baseline, *ctrl_position).to_cubic(),
);
} else if point_count == 4 {
let first_ctrl_point_index = last_endpoint_index as usize + 1;
let ctrl_position_0 = &contour.points[first_ctrl_point_index + 0];
let ctrl_position_1 = &contour.points[first_ctrl_point_index + 1];
let ctrl = LineSegmentF32::new(&ctrl_position_0, &ctrl_position_1);
let ctrl = LineSegmentF32::new(*ctrl_position_0, *ctrl_position_1);
handle_cubic(self, Segment::cubic(&baseline, &ctrl));
}
@ -723,24 +758,21 @@ impl<'a> Iterator for ContourIter<'a> {
if self.index == contour.len() {
let point1 = contour.position_of(0);
self.index += 1;
return Some(Segment::line(&LineSegmentF32::new(&point0, &point1)));
return Some(Segment::line(&LineSegmentF32::new(point0, point1)));
}
let point1_index = self.index;
self.index += 1;
let point1 = contour.position_of(point1_index);
if contour.point_is_endpoint(point1_index) {
return Some(Segment::line(&LineSegmentF32::new(&point0, &point1)));
return Some(Segment::line(&LineSegmentF32::new(point0, point1)));
}
let point2_index = self.index;
let point2 = contour.position_of(point2_index);
self.index += 1;
if contour.point_is_endpoint(point2_index) {
return Some(Segment::quadratic(
&LineSegmentF32::new(&point0, &point2),
&point1,
));
return Some(Segment::quadratic(&LineSegmentF32::new(point0, point2), point1));
}
let point3_index = self.index;
@ -748,8 +780,8 @@ impl<'a> Iterator for ContourIter<'a> {
self.index += 1;
debug_assert!(contour.point_is_endpoint(point3_index));
return Some(Segment::cubic(
&LineSegmentF32::new(&point0, &point3),
&LineSegmentF32::new(&point1, &point2),
&LineSegmentF32::new(point0, point3),
&LineSegmentF32::new(point1, point2),
));
}
}

View File

@ -12,8 +12,10 @@
use crate::basic::line_segment::LineSegmentF32;
use crate::basic::point::Point2DF32;
use crate::basic::transform2d::Transform2DF32;
use crate::util::{self, EPSILON};
use pathfinder_simd::default::F32x4;
use std::f32::consts::SQRT_2;
const MAX_NEWTON_ITERATIONS: u32 = 32;
@ -47,10 +49,10 @@ impl Segment {
}
#[inline]
pub fn quadratic(baseline: &LineSegmentF32, ctrl: &Point2DF32) -> Segment {
pub fn quadratic(baseline: &LineSegmentF32, ctrl: Point2DF32) -> Segment {
Segment {
baseline: *baseline,
ctrl: LineSegmentF32::new(ctrl, &Point2DF32::default()),
ctrl: LineSegmentF32::new(ctrl, Point2DF32::default()),
kind: SegmentKind::Quadratic,
flags: SegmentFlags::empty(),
}
@ -66,6 +68,24 @@ impl Segment {
}
}
/// Approximates an unit-length arc with a cubic Bézier curve.
///
/// The maximum supported `sweep_angle` is π/2 (i.e. 90°).
pub fn arc(sweep_angle: f32) -> Segment {
// Aleksas Riškus, "Approximation of a Cubic Bézier Curve by Circular Arcs and Vice Versa"
// 2006.
//
// https://pdfs.semanticscholar.org/1639/0db1a470bd13fe428e0896671a9a5745070a.pdf
let phi = 0.5 * sweep_angle;
let p0 = Point2DF32::new(f32::cos(phi), f32::sin(phi));
let p3 = p0.scale_xy(Point2DF32::new(1.0, -1.0));
let p1 = p0 - p3.yx().scale(K);
let p2 = p3 + p0.yx().scale(K);
return Segment::cubic(&LineSegmentF32::new(p3, p0), &LineSegmentF32::new(p2, p1));
const K: f32 = 4.0 / 3.0 * (SQRT_2 - 1.0);
}
#[inline]
pub fn as_line_segment(&self) -> LineSegmentF32 {
debug_assert!(self.is_line());
@ -109,7 +129,7 @@ impl Segment {
let mut new_segment = *self;
let p1_2 = self.ctrl.from() + self.ctrl.from();
new_segment.ctrl =
LineSegmentF32::new(&(self.baseline.from() + p1_2), &(p1_2 + self.baseline.to()))
LineSegmentF32::new(self.baseline.from() + p1_2, p1_2 + self.baseline.to())
.scale(1.0 / 3.0);
new_segment.kind = SegmentKind::Cubic;
new_segment
@ -176,6 +196,16 @@ impl Segment {
self.to_cubic().as_cubic_segment().sample(t)
}
}
#[inline]
pub fn transform(self, transform: &Transform2DF32) -> Segment {
Segment {
baseline: transform.transform_line_segment(&self.baseline),
ctrl: transform.transform_line_segment(&self.ctrl),
kind: self.kind,
flags: self.flags,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
@ -215,16 +245,16 @@ impl<'s> CubicSegment<'s> {
let (baseline0, ctrl0, baseline1, ctrl1);
if t <= 0.0 {
let from = &self.0.baseline.from();
baseline0 = LineSegmentF32::new(from, from);
ctrl0 = LineSegmentF32::new(from, from);
baseline0 = LineSegmentF32::new(*from, *from);
ctrl0 = LineSegmentF32::new(*from, *from);
baseline1 = self.0.baseline;
ctrl1 = self.0.ctrl;
} else if t >= 1.0 {
let to = &self.0.baseline.to();
baseline0 = self.0.baseline;
ctrl0 = self.0.ctrl;
baseline1 = LineSegmentF32::new(to, to);
ctrl1 = LineSegmentF32::new(to, to);
baseline1 = LineSegmentF32::new(*to, *to);
ctrl1 = LineSegmentF32::new(*to, *to);
} else {
let tttt = F32x4::splat(t);

View File

@ -118,51 +118,51 @@ impl Offset for Segment {
}
if self.is_quadratic() {
let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.from());
let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.baseline.to());
let mut segment_0 = LineSegmentF32::new(self.baseline.from(), self.ctrl.from());
let mut segment_1 = LineSegmentF32::new(self.ctrl.from(), self.baseline.to());
segment_0 = segment_0.offset(distance);
segment_1 = segment_1.offset(distance);
let ctrl = match segment_0.intersection_t(&segment_1) {
Some(t) => segment_0.sample(t),
None => segment_0.to().lerp(segment_1.from(), 0.5),
};
let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to());
return Segment::quadratic(&baseline, &ctrl);
let baseline = LineSegmentF32::new(segment_0.from(), segment_1.to());
return Segment::quadratic(&baseline, ctrl);
}
debug_assert!(self.is_cubic());
if self.baseline.from() == self.ctrl.from() {
let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.to());
let mut segment_1 = LineSegmentF32::new(&self.ctrl.to(), &self.baseline.to());
let mut segment_0 = LineSegmentF32::new(self.baseline.from(), self.ctrl.to());
let mut segment_1 = LineSegmentF32::new(self.ctrl.to(), self.baseline.to());
segment_0 = segment_0.offset(distance);
segment_1 = segment_1.offset(distance);
let ctrl = match segment_0.intersection_t(&segment_1) {
Some(t) => segment_0.sample(t),
None => segment_0.to().lerp(segment_1.from(), 0.5),
};
let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to());
let ctrl = LineSegmentF32::new(&segment_0.from(), &ctrl);
let baseline = LineSegmentF32::new(segment_0.from(), segment_1.to());
let ctrl = LineSegmentF32::new(segment_0.from(), ctrl);
return Segment::cubic(&baseline, &ctrl);
}
if self.ctrl.to() == self.baseline.to() {
let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.from());
let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.baseline.to());
let mut segment_0 = LineSegmentF32::new(self.baseline.from(), self.ctrl.from());
let mut segment_1 = LineSegmentF32::new(self.ctrl.from(), self.baseline.to());
segment_0 = segment_0.offset(distance);
segment_1 = segment_1.offset(distance);
let ctrl = match segment_0.intersection_t(&segment_1) {
Some(t) => segment_0.sample(t),
None => segment_0.to().lerp(segment_1.from(), 0.5),
};
let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to());
let ctrl = LineSegmentF32::new(&ctrl, &segment_1.to());
let baseline = LineSegmentF32::new(segment_0.from(), segment_1.to());
let ctrl = LineSegmentF32::new(ctrl, segment_1.to());
return Segment::cubic(&baseline, &ctrl);
}
let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.from());
let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.ctrl.to());
let mut segment_2 = LineSegmentF32::new(&self.ctrl.to(), &self.baseline.to());
let mut segment_0 = LineSegmentF32::new(self.baseline.from(), self.ctrl.from());
let mut segment_1 = LineSegmentF32::new(self.ctrl.from(), self.ctrl.to());
let mut segment_2 = LineSegmentF32::new(self.ctrl.to(), self.baseline.to());
segment_0 = segment_0.offset(distance);
segment_1 = segment_1.offset(distance);
segment_2 = segment_2.offset(distance);
@ -176,8 +176,8 @@ impl Offset for Segment {
segment_1.to().lerp(segment_2.from(), 0.5),
),
};
let baseline = LineSegmentF32::new(&segment_0.from(), &segment_2.to());
let ctrl = LineSegmentF32::new(&ctrl_0, &ctrl_1);
let baseline = LineSegmentF32::new(segment_0.from(), segment_2.to());
let ctrl = LineSegmentF32::new(ctrl_0, ctrl_1);
Segment::cubic(&baseline, &ctrl)
}

View File

@ -236,9 +236,9 @@ impl BuiltObject {
let right = Point2DF32::new(right, tile_origin_y);
let segment = if winding < 0 {
LineSegmentF32::new(&left, &right)
LineSegmentF32::new(left, right)
} else {
LineSegmentF32::new(&right, &left)
LineSegmentF32::new(right, left)
};
debug!(
@ -300,14 +300,14 @@ impl BuiltObject {
let point = Point2DF32::new(x, segment.solve_y_for_x(x));
if !winding {
fill_to = point;
segment = LineSegmentF32::new(&point, &segment.to());
segment = LineSegmentF32::new(point, segment.to());
} else {
fill_from = point;
segment = LineSegmentF32::new(&segment.from(), &point);
segment = LineSegmentF32::new(segment.from(), point);
}
}
let fill_segment = LineSegmentF32::new(&fill_from, &fill_to);
let fill_segment = LineSegmentF32::new(fill_from, fill_to);
let fill_tile_coords = Point2DI32::new(subsegment_tile_x, tile_y);
self.add_fill(builder, &fill_segment, fill_tile_coords);
}

View File

@ -129,7 +129,7 @@ impl Scene {
};
if options.subpixel_aa_enabled {
transform = transform
.post_mul(&Transform2DF32::from_scale(&Point2DF32::new(3.0, 1.0)))
.post_mul(&Transform2DF32::from_scale(Point2DF32::new(3.0, 1.0)))
}
outline.transform(&transform);
}

View File

@ -434,8 +434,7 @@ impl ActiveEdge {
// If necessary, draw initial line.
if self.crossing.y() < segment.baseline.min_y() {
let first_line_segment =
LineSegmentF32::new(&self.crossing, &segment.baseline.upper_point())
.orient(winding);
LineSegmentF32::new(self.crossing, segment.baseline.upper_point()).orient(winding);
if self
.process_line_segment(&first_line_segment, builder, built_object, tile_y)
.is_some()

View File

@ -93,7 +93,7 @@ impl SceneExt for Scene {
let scale = style.size / (font.metrics().units_per_em as f32);
let scale = Point2DF32::new(scale, -scale);
let transform =
Transform2DF32::from_scale(&scale).post_mul(transform).post_translate(offset);
Transform2DF32::from_scale(scale).post_mul(transform).post_translate(offset);
self.push_glyph(font,
glyph.glyph_id,
&transform,
@ -147,7 +147,7 @@ impl OutlinePathBuilder {
}
fn convert_point(&self, point: Point2D<f32>) -> Point2DF32 {
self.transform.transform_point(&Point2DF32::new(point.x, point.y))
self.transform.transform_point(Point2DF32::new(point.x, point.y))
}
}