From b60275e5ea6d8d16b4a5d0ff62ea834d3e598b88 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 6 Mar 2018 13:09:51 -0800 Subject: [PATCH] Convert cubic curves to quadratic ones in fonts --- demo/server/src/main.rs | 15 ++-- path-utils/src/cubic_to_quadratic.rs | 68 +++++++++++++++++++ .../gles2/xcaa-mono-subpixel-resolve.fs.glsl | 2 +- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/demo/server/src/main.rs b/demo/server/src/main.rs index de0bf7a3..445fd33e 100644 --- a/demo/server/src/main.rs +++ b/demo/server/src/main.rs @@ -48,6 +48,7 @@ use pathfinder_font_renderer::{GlyphKey, SubpixelOffset}; use pathfinder_partitioner::FillRule; use pathfinder_partitioner::mesh_library::MeshLibrary; use pathfinder_partitioner::partitioner::Partitioner; +use pathfinder_path_utils::cubic_to_quadratic::CubicToQuadraticTransformer; use pathfinder_path_utils::stroke::{StrokeStyle, StrokeToFillIter}; use pathfinder_path_utils::transform::Transform2DPathIter; 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 CUBIC_TO_QUADRATIC_APPROX_TOLERANCE: f32 = 1.0; + static NEXT_FONT_KEY: AtomicUsize = ATOMIC_USIZE_INIT; lazy_static! { @@ -486,10 +489,14 @@ fn partition_font(request: Json) -> Result where I: Iterator { + inner: I, + segment_iter: Option, + last_point: Point2D, + error_bound: f32, +} + +impl CubicToQuadraticTransformer where I: Iterator { + #[inline] + pub fn new(inner: I, error_bound: f32) -> CubicToQuadraticTransformer { + CubicToQuadraticTransformer { + inner: inner, + segment_iter: None, + last_point: Point2D::zero(), + error_bound: error_bound, + } + } +} + +impl Iterator for CubicToQuadraticTransformer where I: Iterator { + type Item = PathEvent; + + fn next(&mut self) -> Option { + 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)) + } + } + } +} diff --git a/shaders/gles2/xcaa-mono-subpixel-resolve.fs.glsl b/shaders/gles2/xcaa-mono-subpixel-resolve.fs.glsl index f567eb26..70973020 100644 --- a/shaders/gles2/xcaa-mono-subpixel-resolve.fs.glsl +++ b/shaders/gles2/xcaa-mono-subpixel-resolve.fs.glsl @@ -26,7 +26,7 @@ uniform ivec2 uAAAlphaDimensions; varying vec2 vTexCoord; 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() {