Various bug fixes

This commit is contained in:
Patrick Walton 2017-07-03 15:32:22 -04:00
parent b546ffebcc
commit ffd167a342
4 changed files with 60 additions and 77 deletions

View File

@ -6,18 +6,8 @@ use std::slice;
use {Bezieroid, ControlPoints, Endpoint, Subpath};
#[no_mangle]
pub unsafe extern fn pf_partitioner_new(endpoints: *const Endpoint,
endpoint_count: u32,
control_points: *const ControlPoints,
control_points_count: u32,
subpaths: *const Subpath,
subpath_count: u32)
-> *mut Partitioner<'static> {
let mut partitioner =
Box::new(Partitioner::new(slice::from_raw_parts(endpoints, endpoint_count as usize),
slice::from_raw_parts(control_points,
control_points_count as usize),
slice::from_raw_parts(subpaths, subpath_count as usize)));
pub unsafe extern fn pf_partitioner_new() -> *mut Partitioner<'static> {
let mut partitioner = Box::new(Partitioner::new());
let partitioner_ptr: *mut Partitioner<'static> = &mut *partitioner;
mem::forget(partitioner);
partitioner_ptr
@ -29,22 +19,23 @@ pub unsafe extern fn pf_partitioner_destroy<'a>(partitioner: *mut Partitioner<'a
}
#[no_mangle]
pub unsafe extern fn pf_partitioner_reset<'a>(partitioner: *mut Partitioner<'a>,
new_endpoints: *const Endpoint,
new_endpoint_count: u32,
new_control_points: *const ControlPoints,
new_control_points_count: u32,
new_subpaths: *const Subpath,
new_subpath_count: u32) {
(*partitioner).reset(slice::from_raw_parts(new_endpoints, new_endpoint_count as usize),
slice::from_raw_parts(new_control_points,
new_control_points_count as usize),
slice::from_raw_parts(new_subpaths, new_subpath_count as usize))
pub unsafe extern fn pf_partitioner_init<'a>(partitioner: *mut Partitioner<'a>,
endpoints: *const Endpoint,
endpoint_count: u32,
control_points: *const ControlPoints,
control_points_count: u32,
subpaths: *const Subpath,
subpath_count: u32) {
(*partitioner).init(slice::from_raw_parts(endpoints, endpoint_count as usize),
slice::from_raw_parts(control_points, control_points_count as usize),
slice::from_raw_parts(subpaths, subpath_count as usize))
}
#[no_mangle]
pub unsafe extern fn pf_partitioner_partition<'a>(partitioner: *mut Partitioner<'a>) {
(*partitioner).partition()
pub unsafe extern fn pf_partitioner_partition<'a>(partitioner: *mut Partitioner<'a>,
first_subpath_index: u32,
last_subpath_index: u32) {
(*partitioner).partition(first_subpath_index, last_subpath_index)
}
#[no_mangle]

View File

@ -47,4 +47,5 @@ pub struct ControlPoints {
#[derive(Debug, Clone, Copy)]
pub struct Subpath {
pub first_endpoint_index: u32,
pub last_endpoint_index: u32,
}

View File

@ -22,14 +22,11 @@ pub struct Partitioner<'a> {
impl<'a> Partitioner<'a> {
#[inline]
pub fn new<'b>(endpoints: &'b [Endpoint],
control_points: &'b [ControlPoints],
subpaths: &'b [Subpath])
-> Partitioner<'b> {
pub fn new<'b>() -> Partitioner<'b> {
Partitioner {
endpoints: endpoints,
control_points: control_points,
subpaths: subpaths,
endpoints: &[],
control_points: &[],
subpaths: &[],
bezieroids: vec![],
@ -39,22 +36,23 @@ impl<'a> Partitioner<'a> {
}
}
pub fn reset(&mut self,
new_endpoints: &'a [Endpoint],
new_control_points: &'a [ControlPoints],
new_subpaths: &'a [Subpath]) {
pub fn init(&mut self,
new_endpoints: &'a [Endpoint],
new_control_points: &'a [ControlPoints],
new_subpaths: &'a [Subpath]) {
self.endpoints = new_endpoints;
self.control_points = new_control_points;
self.subpaths = new_subpaths;
self.visited_points = BitVec::from_elem(self.endpoints.len() * 2, false);
self.bezieroids.clear();
self.heap.clear();
self.visited_points.clear();
self.active_edges.clear();
}
pub fn partition(&mut self) {
self.init_heap();
pub fn partition(&mut self, first_subpath_index: u32, last_subpath_index: u32) {
self.init_heap(first_subpath_index, last_subpath_index);
while self.process_next_point() {}
}
@ -230,14 +228,17 @@ impl<'a> Partitioner<'a> {
}
}
fn init_heap(&mut self) {
for endpoint_index in 0..(self.endpoints.len() as u32) {
match self.classify_endpoint(endpoint_index) {
EndpointClass::Min => {
let new_point = self.create_point_from_endpoint(endpoint_index);
self.heap.push(new_point)
fn init_heap(&mut self, first_subpath_index: u32, last_subpath_index: u32) {
for subpath in &self.subpaths[(first_subpath_index as usize)..
(last_subpath_index as usize)] {
for endpoint_index in subpath.first_endpoint_index..subpath.last_endpoint_index {
match self.classify_endpoint(endpoint_index) {
EndpointClass::Min => {
let new_point = self.create_point_from_endpoint(endpoint_index);
self.heap.push(new_point)
}
EndpointClass::Regular | EndpointClass::Max => {}
}
EndpointClass::Regular | EndpointClass::Max => {}
}
}
}
@ -459,7 +460,7 @@ impl<'a> Partitioner<'a> {
let lower_control_points_index = self.endpoints[next_lower_endpoint_index as usize]
.control_points_index;
match (lower_control_points_index, upper_control_points_index) {
match (upper_control_points_index, lower_control_points_index) {
(u32::MAX, u32::MAX) => {
self.line_line_crossing_point(prev_upper_endpoint_index,
next_upper_endpoint_index,
@ -543,23 +544,21 @@ impl<'a> Partitioner<'a> {
fn prev_endpoint_of(&self, endpoint_index: u32) -> u32 {
let endpoint = &self.endpoints[endpoint_index as usize];
let first_endpoint_index_of_subpath = self.subpaths[endpoint.subpath_index as usize]
.first_endpoint_index;
if endpoint_index > first_endpoint_index_of_subpath {
let subpath = &self.subpaths[endpoint.subpath_index as usize];
if endpoint_index > subpath.first_endpoint_index {
endpoint_index - 1
} else {
self.last_endpoint_index_of_subpath(endpoint.subpath_index) - 1
subpath.last_endpoint_index - 1
}
}
fn next_endpoint_of(&self, endpoint_index: u32) -> u32 {
let endpoint = &self.endpoints[endpoint_index as usize];
let last_endpoint_index_of_subpath =
self.last_endpoint_index_of_subpath(endpoint.subpath_index);
if endpoint_index + 1 < last_endpoint_index_of_subpath {
let subpath = &self.subpaths[endpoint.subpath_index as usize];
if endpoint_index + 1 < subpath.last_endpoint_index {
endpoint_index + 1
} else {
self.subpaths[endpoint.subpath_index as usize].first_endpoint_index
subpath.first_endpoint_index
}
}
@ -570,13 +569,6 @@ impl<'a> Partitioner<'a> {
point_type: PointType::Endpoint,
}
}
fn last_endpoint_index_of_subpath(&self, subpath_index: u32) -> u32 {
match self.subpaths.get(subpath_index as usize + 1) {
Some(subpath) => subpath.first_endpoint_index,
None => self.endpoints.len() as u32,
}
}
}
#[derive(Debug, Clone, Copy)]

View File

@ -18,8 +18,8 @@ typedef struct pf_point2d_f32 pf_point2d_f32_t;
struct pf_bezieroid {
uint32_t upper_prev_endpoint, upper_next_endpoint;
uint32_t lower_prev_endpoint, lower_next_endpoint;
uint32_t upper_left_time, upper_right_time;
uint32_t lower_left_time, lower_right_time;
float upper_left_time, upper_right_time;
float lower_left_time, lower_right_time;
};
typedef struct pf_bezieroid pf_bezieroid_t;
@ -40,6 +40,7 @@ typedef struct pf_control_points pf_control_points_t;
struct pf_subpath {
uint32_t first_endpoint_index;
uint32_t last_endpoint_index;
};
typedef struct pf_subpath pf_subpath_t;
@ -48,23 +49,21 @@ struct pf_partitioner;
typedef struct pf_partitioner pf_partitioner_t;
pf_partitioner_t *pf_partitioner_new(const pf_endpoint_t *endpoints,
uint32_t endpoint_count,
const pf_control_points_t *control_points,
uint32_t control_points_count,
const pf_subpath_t *subpaths,
uint32_t subpath_count);
pf_partitioner_t *pf_partitioner_new();
void pf_partitioner_destroy(pf_partitioner_t *partitioner);
void pf_partitioner_reset(const pf_endpoint_t *new_endpoints,
uint32_t new_endpoint_count,
const pf_control_points_t *new_control_points,
uint32_t new_control_points_count,
const pf_subpath_t *new_subpaths,
uint32_t new_subpath_count);
void pf_partitioner_init(pf_partitioner_t *partitioner,
const pf_endpoint_t *endpoints,
uint32_t endpoint_count,
const pf_control_points_t *control_points,
uint32_t control_points_count,
const pf_subpath_t *subpaths,
uint32_t subpath_count);
void pf_partitioner_partition(pf_partitioner_t *partitioner);
void pf_partitioner_partition(pf_partitioner_t *partitioner,
uint32_t first_subpath_index,
uint32_t last_subpath_index);
const pf_bezieroid_t *pf_partitioner_bezieroids(pf_partitioner_t *partitioner,
uint32_t *out_bezieroid_count);