Convert cubic curves to quadratic ones in fonts
This commit is contained in:
parent
07d978909c
commit
b60275e5ea
|
@ -48,6 +48,7 @@ use pathfinder_font_renderer::{GlyphKey, SubpixelOffset};
|
||||||
use pathfinder_partitioner::FillRule;
|
use pathfinder_partitioner::FillRule;
|
||||||
use pathfinder_partitioner::mesh_library::MeshLibrary;
|
use pathfinder_partitioner::mesh_library::MeshLibrary;
|
||||||
use pathfinder_partitioner::partitioner::Partitioner;
|
use pathfinder_partitioner::partitioner::Partitioner;
|
||||||
|
use pathfinder_path_utils::cubic_to_quadratic::CubicToQuadraticTransformer;
|
||||||
use pathfinder_path_utils::stroke::{StrokeStyle, StrokeToFillIter};
|
use pathfinder_path_utils::stroke::{StrokeStyle, StrokeToFillIter};
|
||||||
use pathfinder_path_utils::transform::Transform2DPathIter;
|
use pathfinder_path_utils::transform::Transform2DPathIter;
|
||||||
use rocket::http::{ContentType, Header, Status};
|
use rocket::http::{ContentType, Header, Status};
|
||||||
|
@ -76,6 +77,8 @@ const SUGGESTED_JSON_SIZE_LIMIT: u64 = 32 * 1024 * 1024;
|
||||||
|
|
||||||
const MESH_LIBRARY_CACHE_SIZE: usize = 16;
|
const MESH_LIBRARY_CACHE_SIZE: usize = 16;
|
||||||
|
|
||||||
|
const CUBIC_TO_QUADRATIC_APPROX_TOLERANCE: f32 = 1.0;
|
||||||
|
|
||||||
static NEXT_FONT_KEY: AtomicUsize = ATOMIC_USIZE_INIT;
|
static NEXT_FONT_KEY: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -486,10 +489,14 @@ fn partition_font(request: Json<PartitionFontRequest>) -> Result<PartitionRespon
|
||||||
// Partition the decoded glyph outlines.
|
// Partition the decoded glyph outlines.
|
||||||
let mut library = MeshLibrary::new();
|
let mut library = MeshLibrary::new();
|
||||||
for (stored_path_index, path_descriptor) in path_descriptors.iter().enumerate() {
|
for (stored_path_index, path_descriptor) in path_descriptors.iter().enumerate() {
|
||||||
library.push_stencil_segments((path_descriptor.path_index + 1) as u16,
|
library.push_stencil_segments(
|
||||||
PathIter::new(paths[stored_path_index].iter().cloned()));
|
(path_descriptor.path_index + 1) as u16,
|
||||||
library.push_stencil_normals((path_descriptor.path_index + 1) as u16,
|
CubicToQuadraticTransformer::new(paths[stored_path_index].iter().cloned(),
|
||||||
paths[stored_path_index].iter().cloned());
|
CUBIC_TO_QUADRATIC_APPROX_TOLERANCE));
|
||||||
|
library.push_stencil_normals(
|
||||||
|
(path_descriptor.path_index + 1) as u16,
|
||||||
|
CubicToQuadraticTransformer::new(paths[stored_path_index].iter().cloned(),
|
||||||
|
CUBIC_TO_QUADRATIC_APPROX_TOLERANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut partitioner = Partitioner::new(library);
|
let mut partitioner = Partitioner::new(library);
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
|
|
||||||
//! A version of Lyon's `cubic_to_quadratic` that is less sensitive to floating point error.
|
//! A version of Lyon's `cubic_to_quadratic` that is less sensitive to floating point error.
|
||||||
|
|
||||||
|
use euclid::Point2D;
|
||||||
use lyon_geom::{CubicBezierSegment, QuadraticBezierSegment};
|
use lyon_geom::{CubicBezierSegment, QuadraticBezierSegment};
|
||||||
|
use lyon_path::PathEvent;
|
||||||
|
|
||||||
const MAX_APPROXIMATION_ITERATIONS: u8 = 32;
|
const MAX_APPROXIMATION_ITERATIONS: u8 = 32;
|
||||||
|
|
||||||
|
@ -67,3 +69,69 @@ impl Iterator for CubicToQuadraticSegmentIter {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CubicToQuadraticTransformer<I> where I: Iterator<Item = PathEvent> {
|
||||||
|
inner: I,
|
||||||
|
segment_iter: Option<CubicToQuadraticSegmentIter>,
|
||||||
|
last_point: Point2D<f32>,
|
||||||
|
error_bound: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> CubicToQuadraticTransformer<I> where I: Iterator<Item = PathEvent> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(inner: I, error_bound: f32) -> CubicToQuadraticTransformer<I> {
|
||||||
|
CubicToQuadraticTransformer {
|
||||||
|
inner: inner,
|
||||||
|
segment_iter: None,
|
||||||
|
last_point: Point2D::zero(),
|
||||||
|
error_bound: error_bound,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> Iterator for CubicToQuadraticTransformer<I> where I: Iterator<Item = PathEvent> {
|
||||||
|
type Item = PathEvent;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<PathEvent> {
|
||||||
|
if let Some(ref mut segment_iter) = self.segment_iter {
|
||||||
|
if let Some(quadratic) = segment_iter.next() {
|
||||||
|
return Some(PathEvent::QuadraticTo(quadratic.ctrl, quadratic.to))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.segment_iter = None;
|
||||||
|
|
||||||
|
match self.inner.next() {
|
||||||
|
None => None,
|
||||||
|
Some(PathEvent::CubicTo(ctrl1, ctrl2, to)) => {
|
||||||
|
let cubic = CubicBezierSegment {
|
||||||
|
from: self.last_point,
|
||||||
|
ctrl1: ctrl1,
|
||||||
|
ctrl2: ctrl2,
|
||||||
|
to: to,
|
||||||
|
};
|
||||||
|
self.last_point = to;
|
||||||
|
self.segment_iter = Some(CubicToQuadraticSegmentIter::new(&cubic,
|
||||||
|
self.error_bound));
|
||||||
|
self.next()
|
||||||
|
}
|
||||||
|
Some(PathEvent::MoveTo(to)) => {
|
||||||
|
self.last_point = to;
|
||||||
|
Some(PathEvent::MoveTo(to))
|
||||||
|
}
|
||||||
|
Some(PathEvent::LineTo(to)) => {
|
||||||
|
self.last_point = to;
|
||||||
|
Some(PathEvent::LineTo(to))
|
||||||
|
}
|
||||||
|
Some(PathEvent::QuadraticTo(ctrl, to)) => {
|
||||||
|
self.last_point = to;
|
||||||
|
Some(PathEvent::QuadraticTo(ctrl, to))
|
||||||
|
}
|
||||||
|
Some(PathEvent::Close) => Some(PathEvent::Close),
|
||||||
|
Some(PathEvent::Arc(to, vector, angle_from, angle_to)) => {
|
||||||
|
self.last_point = to;
|
||||||
|
Some(PathEvent::Arc(to, vector, angle_from, angle_to))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ uniform ivec2 uAAAlphaDimensions;
|
||||||
varying vec2 vTexCoord;
|
varying vec2 vTexCoord;
|
||||||
|
|
||||||
float sampleSource(float deltaX) {
|
float sampleSource(float deltaX) {
|
||||||
return texture2D(uAAAlpha, vec2(vTexCoord.s + deltaX, vTexCoord.y)).r;
|
return abs(texture2D(uAAAlpha, vec2(vTexCoord.s + deltaX, vTexCoord.y)).r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
Loading…
Reference in New Issue