Split out B-vertex positions and info so that they're easier to pack into textures
This commit is contained in:
parent
fa1b2390c7
commit
57ebbf8281
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue