Split out B-vertex positions and info so that they're easier to pack into textures

This commit is contained in:
Patrick Walton 2017-08-11 15:56:07 -07:00
parent fa1b2390c7
commit 57ebbf8281
6 changed files with 141 additions and 111 deletions

View File

@ -14,11 +14,13 @@ class PathfinderMeshes {
if (!('Ok' in response)) if (!('Ok' in response))
throw new Error("Failed to partition the font!"); throw new Error("Failed to partition the font!");
const meshes = response.Ok; const meshes = response.Ok;
this.bQuads = base64js.toByteArray(meshes.bQuads); this.bQuadPositions = base64js.toByteArray(meshes.bQuadPositions);
this.bQuadInfo = base64js.toByteArray(meshes.bQuadInfo);
this.bVertices = base64js.toByteArray(meshes.bVertices); this.bVertices = base64js.toByteArray(meshes.bVertices);
} }
bQuads: ArrayBuffer; bQuadPositions: ArrayBuffer;
bQuadInfo: ArrayBuffer;
bVertices: ArrayBuffer; bVertices: ArrayBuffer;
} }

View File

@ -121,8 +121,10 @@ struct PartitionFontResponse {
glyphInfo: Vec<PartitionGlyphInfo>, glyphInfo: Vec<PartitionGlyphInfo>,
// Base64-encoded `bincode`-encoded `BQuad`s. // Base64-encoded `bincode`-encoded `BQuad`s.
bQuads: String, bQuads: String,
// Base64-encoded `bincode`-encoded `BVertex`es. // Base64-encoded `bincode`-encoded `Point2D<f32>`s.
bVertices: String, bVertexPositions: String,
// Base64-encoded `bincode`-encoded `BVertexInfo`s.
bVertexInfo: String,
coverInteriorIndices: Vec<u32>, coverInteriorIndices: Vec<u32>,
coverCurveIndices: Vec<u32>, coverCurveIndices: Vec<u32>,
// Base64-encoded `bincode`-encoded `LineIndices` instances. // Base64-encoded `bincode`-encoded `LineIndices` instances.
@ -195,7 +197,7 @@ fn partition_font(request: Json<PartitionFontRequest>)
// Partition the decoded glyph outlines. // Partition the decoded glyph outlines.
let mut partitioner = Partitioner::new(); let mut partitioner = Partitioner::new();
let (mut b_quads, mut b_vertices) = (vec![], vec![]); let (mut b_quads, mut b_vertex_positions, mut b_vertex_info) = (vec![], vec![], vec![]);
let (mut cover_interior_indices, mut cover_curve_indices) = (vec![], vec![]); let (mut cover_interior_indices, mut cover_curve_indices) = (vec![], vec![]);
let (mut edge_upper_line_indices, mut edge_upper_curve_indices) = (vec![], vec![]); let (mut edge_upper_line_indices, mut edge_upper_curve_indices) = (vec![], vec![]);
let (mut edge_lower_line_indices, mut edge_lower_curve_indices) = (vec![], vec![]); let (mut edge_lower_line_indices, mut edge_lower_curve_indices) = (vec![], vec![]);
@ -228,18 +230,23 @@ fn partition_font(request: Json<PartitionFontRequest>)
decoded_outline_indices.subpath_indices.start as u32, decoded_outline_indices.subpath_indices.start as u32,
decoded_outline_indices.subpath_indices.end as u32); decoded_outline_indices.subpath_indices.end as u32);
let (path_b_quads, path_b_vertices) = (partitioner.b_quads(), partitioner.b_vertices()); let path_b_quads = partitioner.b_quads();
let path_b_vertex_positions = partitioner.b_vertex_positions();
let path_b_vertex_info = partitioner.b_vertex_info();
let cover_indices = partitioner.cover_indices(); let cover_indices = partitioner.cover_indices();
let edge_indices = partitioner.edge_indices(); let edge_indices = partitioner.edge_indices();
IndexRange::from_vector_append_and_serialization(&mut b_vertex_positions,
path_b_vertex_positions).unwrap();
glyph_info.push(PartitionGlyphInfo { glyph_info.push(PartitionGlyphInfo {
id: glyph_id, id: glyph_id,
dimensions: dimensions, dimensions: dimensions,
bQuadIndices: IndexRange::from_vector_append_and_serialization(&mut b_quads, bQuadIndices: IndexRange::from_vector_append_and_serialization(&mut b_quads,
path_b_quads).unwrap(), path_b_quads).unwrap(),
bVertexIndices: bVertexIndices:
IndexRange::from_vector_append_and_serialization(&mut b_vertices, IndexRange::from_vector_append_and_serialization(&mut b_vertex_info,
path_b_vertices).unwrap(), path_b_vertex_info).unwrap(),
coverInteriorIndices: coverInteriorIndices:
IndexRange::from_vector_append_operation(&mut cover_interior_indices, IndexRange::from_vector_append_operation(&mut cover_interior_indices,
cover_indices.interior_indices), cover_indices.interior_indices),
@ -265,7 +272,8 @@ fn partition_font(request: Json<PartitionFontRequest>)
Json(Ok(PartitionFontResponse { Json(Ok(PartitionFontResponse {
glyphInfo: glyph_info, glyphInfo: glyph_info,
bQuads: base64::encode(&b_quads), bQuads: base64::encode(&b_quads),
bVertices: base64::encode(&b_vertices), bVertexPositions: base64::encode(&b_vertex_positions),
bVertexInfo: base64::encode(&b_vertex_info),
coverInteriorIndices: cover_interior_indices, coverInteriorIndices: cover_interior_indices,
coverCurveIndices: cover_curve_indices, coverCurveIndices: cover_curve_indices,
edgeUpperLineIndices: base64::encode(&edge_upper_line_indices), edgeUpperLineIndices: base64::encode(&edge_upper_line_indices),

View File

@ -6,7 +6,7 @@ use legalizer::Legalizer;
use partitioner::Partitioner; use partitioner::Partitioner;
use std::mem; use std::mem;
use std::slice; use std::slice;
use {BQuad, BVertex, CurveIndices, Endpoint, LineIndices, Subpath}; use {BQuad, BVertexInfo, CurveIndices, Endpoint, LineIndices, Subpath};
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
#[repr(C)] #[repr(C)]
@ -184,15 +184,25 @@ pub unsafe extern fn pf_partitioner_b_quads<'a>(partitioner: *const Partitioner<
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn pf_partitioner_b_vertices<'a>(partitioner: *const Partitioner<'a>, pub unsafe extern fn pf_partitioner_b_vertex_positions<'a>(partitioner: *const Partitioner<'a>,
out_b_vertex_count: *mut u32) out_b_vertex_count: *mut u32)
-> *const BVertex { -> *const Point2D<f32> {
// FIXME(pcwalton): This is unsafe! `Point2D<f32>` and `Point2DF32` may have different layouts! let b_vertex_positions = (*partitioner).b_vertex_positions();
let b_vertices = (*partitioner).b_vertices();
if !out_b_vertex_count.is_null() { if !out_b_vertex_count.is_null() {
*out_b_vertex_count = b_vertices.len() as u32 *out_b_vertex_count = b_vertex_positions.len() as u32
} }
b_vertices.as_ptr() as *const BVertex b_vertex_positions.as_ptr() as *const Point2D<f32>
}
#[no_mangle]
pub unsafe extern fn pf_partitioner_b_vertex_info<'a>(partitioner: *const Partitioner<'a>,
out_b_vertex_count: *mut u32)
-> *const BVertexInfo {
let b_vertex_info = (*partitioner).b_vertex_info();
if !out_b_vertex_count.is_null() {
*out_b_vertex_count = b_vertex_info.len() as u32
}
b_vertex_info.as_ptr() as *const BVertexInfo
} }
#[no_mangle] #[no_mangle]

View File

@ -91,24 +91,22 @@ pub enum BVertexKind {
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
#[repr(C)] #[repr(C)]
pub struct BVertex { pub struct BVertexInfo {
pub position: Point2D<f32>,
pub path_id: u32, pub path_id: u32,
pub tex_coord: [u8; 2], pub tex_coord: [u8; 2],
pub kind: BVertexKind, pub kind: BVertexKind,
pad: u8, pad: u8,
} }
impl BVertex { impl BVertexInfo {
#[inline] #[inline]
pub fn new(position: &Point2D<f32>, kind: BVertexKind, path_id: u32) -> BVertex { pub fn new(kind: BVertexKind, path_id: u32) -> BVertexInfo {
let tex_coord = match kind { let tex_coord = match kind {
BVertexKind::Endpoint0 => [0, 0], BVertexKind::Endpoint0 => [0, 0],
BVertexKind::Endpoint1 => [2, 2], BVertexKind::Endpoint1 => [2, 2],
BVertexKind::ConcaveControlPoint | BVertexKind::ConvexControlPoint => [1, 0], BVertexKind::ConcaveControlPoint | BVertexKind::ConvexControlPoint => [1, 0],
}; };
BVertex { BVertexInfo {
position: *position,
path_id: path_id, path_id: path_id,
tex_coord: tex_coord, tex_coord: tex_coord,
kind: kind, kind: kind,
@ -121,7 +119,7 @@ impl BVertex {
right_endpoint_position: &Point2D<f32>, right_endpoint_position: &Point2D<f32>,
path_id: u32, path_id: u32,
bottom: bool) bottom: bool)
-> BVertex { -> BVertexInfo {
let control_point_vector = *control_point_position - *left_endpoint_position; let control_point_vector = *control_point_position - *left_endpoint_position;
let right_vector = *right_endpoint_position - *left_endpoint_position; let right_vector = *right_endpoint_position - *left_endpoint_position;
let determinant = right_vector.cross(control_point_vector); let determinant = right_vector.cross(control_point_vector);
@ -130,7 +128,7 @@ impl BVertex {
} else { } else {
BVertexKind::ConcaveControlPoint BVertexKind::ConcaveControlPoint
}; };
BVertex::new(control_point_position, endpoint_kind, path_id) BVertexInfo::new(endpoint_kind, path_id)
} }
} }

View File

@ -37,15 +37,14 @@ struct pf_matrix2d_f32 {
typedef struct pf_matrix2d_f32 pf_matrix2d_f32_t; typedef struct pf_matrix2d_f32 pf_matrix2d_f32_t;
struct pf_b_vertex { struct pf_b_vertex_info {
pf_point2d_f32_t position;
uint32_t path_id; uint32_t path_id;
uint8_t tex_coord[2]; uint8_t tex_coord[2];
pf_b_vertex_kind_t kind; pf_b_vertex_kind_t kind;
uint8_t pad; uint8_t pad;
}; };
typedef struct pf_b_vertex pf_b_vertex_t; typedef struct pf_b_vertex_info pf_b_vertex_info_t;
struct pf_cover_indices { struct pf_cover_indices {
const uint32_t *interior_indices; const uint32_t *interior_indices;
@ -169,8 +168,11 @@ void pf_partitioner_partition(pf_partitioner_t *partitioner,
const pf_b_quad_t *pf_partitioner_b_quads(const pf_partitioner_t *partitioner, const pf_b_quad_t *pf_partitioner_b_quads(const pf_partitioner_t *partitioner,
uint32_t *out_b_quad_count); uint32_t *out_b_quad_count);
const pf_b_vertex_t *pf_partitioner_b_vertices(const pf_partitioner_t *partitioner, const pf_point2d_f32_t *pf_partitioner_b_vertex_positions(const pf_partitioner_t *partitioner,
uint32_t *out_b_vertex_count); uint32_t *out_b_vertex_count);
const pf_b_vertex_info_t *pf_partitioner_b_vertex_info(const pf_partitioner_t *partitioner,
uint32_t *out_b_vertex_count);
const void pf_partitioner_cover_indices(const pf_partitioner_t *partitioner, const void pf_partitioner_cover_indices(const pf_partitioner_t *partitioner,
pf_cover_indices_t *out_cover_indices); pf_cover_indices_t *out_cover_indices);

View File

@ -8,7 +8,7 @@ use std::collections::BinaryHeap;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::f32; use std::f32;
use std::u32; use std::u32;
use {BQuad, BVertex, BVertexKind, CurveIndices, Endpoint, LineIndices, Subpath}; use {BQuad, BVertexInfo, BVertexKind, CurveIndices, Endpoint, LineIndices, Subpath};
pub struct Partitioner<'a> { pub struct Partitioner<'a> {
endpoints: &'a [Endpoint], endpoints: &'a [Endpoint],
@ -16,7 +16,8 @@ pub struct Partitioner<'a> {
subpaths: &'a [Subpath], subpaths: &'a [Subpath],
b_quads: Vec<BQuad>, b_quads: Vec<BQuad>,
b_vertices: Vec<BVertex>, b_vertex_positions: Vec<Point2D<f32>>,
b_vertex_info: Vec<BVertexInfo>,
cover_indices: CoverIndicesBuffer, cover_indices: CoverIndicesBuffer,
edge_indices: EdgeIndicesBuffer, edge_indices: EdgeIndicesBuffer,
@ -35,7 +36,8 @@ impl<'a> Partitioner<'a> {
subpaths: &[], subpaths: &[],
b_quads: vec![], b_quads: vec![],
b_vertices: vec![], b_vertex_positions: vec![],
b_vertex_info: vec![],
cover_indices: CoverIndicesBuffer::new(), cover_indices: CoverIndicesBuffer::new(),
edge_indices: EdgeIndicesBuffer::new(), edge_indices: EdgeIndicesBuffer::new(),
@ -61,7 +63,8 @@ impl<'a> Partitioner<'a> {
pub fn partition(&mut self, path_id: u32, first_subpath_index: u32, last_subpath_index: u32) { pub fn partition(&mut self, path_id: u32, first_subpath_index: u32, last_subpath_index: u32) {
self.b_quads.clear(); self.b_quads.clear();
self.b_vertices.clear(); self.b_vertex_info.clear();
self.b_vertex_positions.clear();
self.cover_indices.clear(); self.cover_indices.clear();
self.edge_indices.clear(); self.edge_indices.clear();
self.heap.clear(); self.heap.clear();
@ -80,8 +83,13 @@ impl<'a> Partitioner<'a> {
} }
#[inline] #[inline]
pub fn b_vertices(&self) -> &[BVertex] { pub fn b_vertex_positions(&self) -> &[Point2D<f32>] {
&self.b_vertices &self.b_vertex_positions
}
#[inline]
pub fn b_vertex_info(&self) -> &[BVertexInfo] {
&self.b_vertex_info
} }
#[inline] #[inline]
@ -172,13 +180,13 @@ impl<'a> Partitioner<'a> {
{ {
let active_edge = &mut self.active_edges[active_edge_index as usize]; let active_edge = &mut self.active_edges[active_edge_index as usize];
active_edge.left_vertex_index = self.b_vertices.len() as u32; active_edge.left_vertex_index = self.b_vertex_info.len() as u32;
active_edge.control_point_vertex_index = active_edge.left_vertex_index + 1; active_edge.control_point_vertex_index = active_edge.left_vertex_index + 1;
let endpoint_position = self.endpoints[active_edge.right_endpoint_index as usize] let endpoint_position = self.endpoints[active_edge.right_endpoint_index as usize]
.position; .position;
self.b_vertices self.b_vertex_positions.push(endpoint_position);
.push(BVertex::new(&endpoint_position, active_edge.endpoint_kind(), self.path_id)); self.b_vertex_info.push(BVertexInfo::new(active_edge.endpoint_kind(), self.path_id));
active_edge.toggle_parity(); active_edge.toggle_parity();
@ -206,18 +214,19 @@ impl<'a> Partitioner<'a> {
} }
control_point_index => { control_point_index => {
self.active_edges[active_edge_index as usize].control_point_vertex_index = self.active_edges[active_edge_index as usize].control_point_vertex_index =
self.b_vertices.len() as u32; self.b_vertex_info.len() as u32;
let left_vertex_index = self.active_edges[active_edge_index as usize] let left_vertex_index = self.active_edges[active_edge_index as usize]
.left_vertex_index; .left_vertex_index;
let control_point_position = &self.control_points[control_point_index as usize]; let control_point_position = &self.control_points[control_point_index as usize];
let control_point_b_vertex = let control_point_b_vertex_info = BVertexInfo::control_point(
BVertex::control_point(&self.b_vertices[left_vertex_index as usize].position, &self.b_vertex_positions[left_vertex_index as usize],
&control_point_position, &control_point_position,
&new_point.position, &new_point.position,
self.path_id, self.path_id,
bottom); bottom);
self.b_vertices.push(control_point_b_vertex) self.b_vertex_positions.push(*control_point_position);
self.b_vertex_info.push(control_point_b_vertex_info);
} }
} }
} }
@ -271,12 +280,13 @@ impl<'a> Partitioner<'a> {
let new_active_edges = &mut self.active_edges[next_active_edge_index as usize.. let new_active_edges = &mut self.active_edges[next_active_edge_index as usize..
next_active_edge_index as usize + 2]; next_active_edge_index as usize + 2];
let left_vertex_index = self.b_vertices.len() as u32; let left_vertex_index = self.b_vertex_info.len() as u32;
new_active_edges[0].left_vertex_index = left_vertex_index; new_active_edges[0].left_vertex_index = left_vertex_index;
new_active_edges[1].left_vertex_index = left_vertex_index; new_active_edges[1].left_vertex_index = left_vertex_index;
let position = self.endpoints[endpoint_index as usize].position; let position = self.endpoints[endpoint_index as usize].position;
self.b_vertices.push(BVertex::new(&position, BVertexKind::Endpoint0, self.path_id)); self.b_vertex_positions.push(position);
self.b_vertex_info.push(BVertexInfo::new(BVertexKind::Endpoint0, self.path_id));
new_active_edges[0].toggle_parity(); new_active_edges[0].toggle_parity();
new_active_edges[1].toggle_parity(); new_active_edges[1].toggle_parity();
@ -312,36 +322,40 @@ impl<'a> Partitioner<'a> {
match upper_control_point_index { match upper_control_point_index {
u32::MAX => new_active_edges[0].control_point_vertex_index = u32::MAX, u32::MAX => new_active_edges[0].control_point_vertex_index = u32::MAX,
upper_control_point_index => { upper_control_point_index => {
new_active_edges[0].control_point_vertex_index = self.b_vertices.len() as u32; new_active_edges[0].control_point_vertex_index = self.b_vertex_info.len() as u32;
let control_point_position = let control_point_position =
self.control_points[upper_control_point_index as usize]; self.control_points[upper_control_point_index as usize];
let right_vertex_position = let right_vertex_position =
self.endpoints[new_active_edges[0].right_endpoint_index as usize].position; self.endpoints[new_active_edges[0].right_endpoint_index as usize].position;
let control_point_b_vertex = BVertex::control_point(&position, let control_point_b_vertex_info =
&control_point_position, BVertexInfo::control_point(&position,
&right_vertex_position, &control_point_position,
self.path_id, &right_vertex_position,
false); self.path_id,
self.b_vertices.push(control_point_b_vertex) false);
self.b_vertex_positions.push(control_point_position);
self.b_vertex_info.push(control_point_b_vertex_info);
} }
} }
match lower_control_point_index { match lower_control_point_index {
u32::MAX => new_active_edges[1].control_point_vertex_index = u32::MAX, u32::MAX => new_active_edges[1].control_point_vertex_index = u32::MAX,
lower_control_point_index => { lower_control_point_index => {
new_active_edges[1].control_point_vertex_index = self.b_vertices.len() as u32; new_active_edges[1].control_point_vertex_index = self.b_vertex_info.len() as u32;
let control_point_position = let control_point_position =
self.control_points[lower_control_point_index as usize]; self.control_points[lower_control_point_index as usize];
let right_vertex_position = let right_vertex_position =
self.endpoints[new_active_edges[1].right_endpoint_index as usize].position; self.endpoints[new_active_edges[1].right_endpoint_index as usize].position;
let control_point_b_vertex = BVertex::control_point(&position, let control_point_b_vertex_info =
&control_point_position, BVertexInfo::control_point(&position,
&right_vertex_position, &control_point_position,
self.path_id, &right_vertex_position,
true); self.path_id,
self.b_vertices.push(control_point_b_vertex) true);
self.b_vertex_positions.push(control_point_position);
self.b_vertex_info.push(control_point_b_vertex_info);
} }
} }
} }
@ -419,8 +433,8 @@ impl<'a> Partitioner<'a> {
// NB: Order is important here—we depend on the provoking vertex! // NB: Order is important here—we depend on the provoking vertex!
let upper_shape = upper_curve.shape(&self.b_vertices); let upper_shape = upper_curve.shape(&self.b_vertex_info);
let lower_shape = lower_curve.shape(&self.b_vertices); let lower_shape = lower_curve.shape(&self.b_vertex_info);
match upper_shape { match upper_shape {
Shape::Flat => { Shape::Flat => {
@ -627,8 +641,8 @@ impl<'a> Partitioner<'a> {
} }
fn solve_active_edge_t_for_x(&self, x: f32, active_edge: &ActiveEdge) -> f32 { fn solve_active_edge_t_for_x(&self, x: f32, active_edge: &ActiveEdge) -> f32 {
let left_vertex_position = &self.b_vertices[active_edge.left_vertex_index as usize] let left_vertex_position = &self.b_vertex_positions[active_edge.left_vertex_index as
.position; usize];
let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize] let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize]
.position; .position;
match active_edge.control_point_vertex_index { match active_edge.control_point_vertex_index {
@ -636,7 +650,7 @@ impl<'a> Partitioner<'a> {
geometry::solve_line_t_for_x(x, left_vertex_position, right_endpoint_position) geometry::solve_line_t_for_x(x, left_vertex_position, right_endpoint_position)
} }
control_point_vertex_index => { control_point_vertex_index => {
let control_point = &self.b_vertices[control_point_vertex_index as usize].position; let control_point = &self.b_vertex_positions[control_point_vertex_index as usize];
geometry::solve_quadratic_bezier_t_for_x(x, geometry::solve_quadratic_bezier_t_for_x(x,
left_vertex_position, left_vertex_position,
control_point, control_point,
@ -650,8 +664,8 @@ impl<'a> Partitioner<'a> {
} }
fn sample_active_edge(&self, t: f32, active_edge: &ActiveEdge) -> Point2D<f32> { fn sample_active_edge(&self, t: f32, active_edge: &ActiveEdge) -> Point2D<f32> {
let left_vertex_position = &self.b_vertices[active_edge.left_vertex_index as usize] let left_vertex_position = &self.b_vertex_positions[active_edge.left_vertex_index as
.position; usize];
let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize] let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize]
.position; .position;
match active_edge.control_point_vertex_index { match active_edge.control_point_vertex_index {
@ -661,7 +675,7 @@ impl<'a> Partitioner<'a> {
.to_point() .to_point()
} }
control_point_vertex_index => { control_point_vertex_index => {
let control_point = &self.b_vertices[control_point_vertex_index as usize].position; let control_point = &self.b_vertex_positions[control_point_vertex_index as usize];
geometry::sample_quadratic_bezier(t, geometry::sample_quadratic_bezier(t,
left_vertex_position, left_vertex_position,
control_point, control_point,
@ -682,11 +696,11 @@ impl<'a> Partitioner<'a> {
} }
let upper_left_vertex_position = let upper_left_vertex_position =
&self.b_vertices[upper_active_edge.left_vertex_index as usize].position; &self.b_vertex_positions[upper_active_edge.left_vertex_index as usize];
let upper_right_endpoint_position = let upper_right_endpoint_position =
&self.endpoints[upper_active_edge.right_endpoint_index as usize].position; &self.endpoints[upper_active_edge.right_endpoint_index as usize].position;
let lower_left_vertex_position = let lower_left_vertex_position =
&self.b_vertices[lower_active_edge.left_vertex_index as usize].position; &self.b_vertex_positions[lower_active_edge.left_vertex_index as usize];
let lower_right_endpoint_position = let lower_right_endpoint_position =
&self.endpoints[lower_active_edge.right_endpoint_index as usize].position; &self.endpoints[lower_active_edge.right_endpoint_index as usize].position;
@ -700,7 +714,7 @@ impl<'a> Partitioner<'a> {
} }
(upper_control_point_vertex_index, u32::MAX) => { (upper_control_point_vertex_index, u32::MAX) => {
let upper_control_point = let upper_control_point =
&self.b_vertices[upper_control_point_vertex_index as usize].position; &self.b_vertex_positions[upper_control_point_vertex_index as usize];
geometry::line_quadratic_bezier_crossing_point(lower_left_vertex_position, geometry::line_quadratic_bezier_crossing_point(lower_left_vertex_position,
lower_right_endpoint_position, lower_right_endpoint_position,
upper_left_vertex_position, upper_left_vertex_position,
@ -709,7 +723,7 @@ impl<'a> Partitioner<'a> {
} }
(u32::MAX, lower_control_point_vertex_index) => { (u32::MAX, lower_control_point_vertex_index) => {
let lower_control_point = let lower_control_point =
&self.b_vertices[lower_control_point_vertex_index as usize].position; &self.b_vertex_positions[lower_control_point_vertex_index as usize];
geometry::line_quadratic_bezier_crossing_point(upper_left_vertex_position, geometry::line_quadratic_bezier_crossing_point(upper_left_vertex_position,
upper_right_endpoint_position, upper_right_endpoint_position,
lower_left_vertex_position, lower_left_vertex_position,
@ -718,9 +732,9 @@ impl<'a> Partitioner<'a> {
} }
(upper_control_point_vertex_index, lower_control_point_vertex_index) => { (upper_control_point_vertex_index, lower_control_point_vertex_index) => {
let upper_control_point = let upper_control_point =
&self.b_vertices[upper_control_point_vertex_index as usize].position; &self.b_vertex_positions[upper_control_point_vertex_index as usize];
let lower_control_point = let lower_control_point =
&self.b_vertices[lower_control_point_vertex_index as usize].position; &self.b_vertex_positions[lower_control_point_vertex_index as usize];
geometry::quadratic_bezier_quadratic_bezier_crossing_point( geometry::quadratic_bezier_quadratic_bezier_crossing_point(
upper_left_vertex_position, upper_left_vertex_position,
upper_control_point, upper_control_point,
@ -743,57 +757,53 @@ impl<'a> Partitioner<'a> {
let left_curve_control_point_vertex_index; let left_curve_control_point_vertex_index;
match active_edge.control_point_vertex_index { match active_edge.control_point_vertex_index {
u32::MAX => { u32::MAX => {
let left_point = self.b_vertices[left_curve_left as usize]; let path_id = self.b_vertex_info[left_curve_left as usize].path_id;
let left_point_position = self.b_vertex_positions[left_curve_left as usize];
let right_point = self.endpoints[active_edge.right_endpoint_index as usize] let right_point = self.endpoints[active_edge.right_endpoint_index as usize]
.position; .position;
let middle_point = left_point.position.to_vector().lerp(right_point.to_vector(), t); let middle_point = left_point_position.to_vector().lerp(right_point.to_vector(), t);
active_edge.left_vertex_index = self.b_vertices.len() as u32; active_edge.left_vertex_index = self.b_vertex_info.len() as u32;
self.b_vertices.push(BVertex::new(&middle_point.to_point(), self.b_vertex_positions.push(middle_point.to_point());
active_edge.endpoint_kind(), self.b_vertex_info.push(BVertexInfo::new(active_edge.endpoint_kind(), path_id));
left_point.path_id));
active_edge.toggle_parity(); active_edge.toggle_parity();
left_curve_control_point_vertex_index = u32::MAX; left_curve_control_point_vertex_index = u32::MAX;
} }
_ => { _ => {
let left_endpoint_position = self.b_vertices[active_edge.left_vertex_index as usize] let left_endpoint_position =
.position; self.b_vertex_positions[active_edge.left_vertex_index as usize];
let right_endpoint_position = let right_endpoint_position =
self.endpoints[active_edge.right_endpoint_index as usize].position; self.endpoints[active_edge.right_endpoint_index as usize].position;
let subdivided_quadratic_bezier = SubdividedQuadraticBezier::new( let subdivided_quadratic_bezier = SubdividedQuadraticBezier::new(
t, t,
&left_endpoint_position, &left_endpoint_position,
&self.b_vertices[active_edge.control_point_vertex_index as usize].position, &self.b_vertex_positions[active_edge.control_point_vertex_index as usize],
&right_endpoint_position); &right_endpoint_position);
let control_point_b_vertex_a = left_curve_control_point_vertex_index = self.b_vertex_info.len() as u32;
BVertex::control_point(&left_endpoint_position,
&subdivided_quadratic_bezier.ap1,
&subdivided_quadratic_bezier.ap2bp0,
self.path_id,
bottom);
left_curve_control_point_vertex_index = self.b_vertices.len() as u32;
active_edge.left_vertex_index = left_curve_control_point_vertex_index + 1; active_edge.left_vertex_index = left_curve_control_point_vertex_index + 1;
active_edge.control_point_vertex_index = left_curve_control_point_vertex_index + 2;
self.b_vertices.extend([ self.b_vertex_positions.extend([
control_point_b_vertex_a, subdivided_quadratic_bezier.ap1,
BVertex::new(&subdivided_quadratic_bezier.ap2bp0, subdivided_quadratic_bezier.ap2bp0,
active_edge.endpoint_kind(), subdivided_quadratic_bezier.bp1,
self.path_id) ].into_iter());
self.b_vertex_info.extend([
BVertexInfo::control_point(&left_endpoint_position,
&subdivided_quadratic_bezier.ap1,
&subdivided_quadratic_bezier.ap2bp0,
self.path_id,
bottom),
BVertexInfo::new(active_edge.endpoint_kind(), self.path_id),
BVertexInfo::control_point(&subdivided_quadratic_bezier.ap2bp0,
&subdivided_quadratic_bezier.bp1,
&right_endpoint_position,
self.path_id,
bottom),
].into_iter()); ].into_iter());
let control_point_b_vertex_b =
BVertex::control_point(&subdivided_quadratic_bezier.ap2bp0,
&subdivided_quadratic_bezier.bp1,
&right_endpoint_position,
self.path_id,
bottom);
active_edge.control_point_vertex_index = self.b_vertices.len() as u32;
self.b_vertices.push(control_point_b_vertex_b);
active_edge.toggle_parity(); active_edge.toggle_parity();
} }
@ -1005,11 +1015,11 @@ struct SubdividedActiveEdge {
} }
impl SubdividedActiveEdge { impl SubdividedActiveEdge {
fn shape(&self, b_vertices: &[BVertex]) -> Shape { fn shape(&self, b_vertex_info: &[BVertexInfo]) -> Shape {
if self.left_curve_control_point == u32::MAX { if self.left_curve_control_point == u32::MAX {
return Shape::Flat return Shape::Flat
} }
match b_vertices[self.left_curve_control_point as usize].kind { match b_vertex_info[self.left_curve_control_point as usize].kind {
BVertexKind::ConvexControlPoint => Shape::Convex, BVertexKind::ConvexControlPoint => Shape::Convex,
_ => Shape::Concave, _ => Shape::Concave,
} }