diff --git a/src/path/cache.rs b/src/path/cache.rs index 5c1e54fb..d6e83f9b 100644 --- a/src/path/cache.rs +++ b/src/path/cache.rs @@ -540,6 +540,9 @@ impl PathCache { contour.stroke.clear(); contour.fill.clear(); + let triangle_count = (contour.fill.capacity() - 2) * 3; + let mut triangle_fan_fill = Vec::with_capacity(triangle_count); + // TODO: woff = 0.0 produces no artifaacts for small sizes let woff = 0.5 * fringe_width; //let woff = 0.0; // Makes everything thicker @@ -549,25 +552,36 @@ impl PathCache { if p1.flags.contains(PointFlags::BEVEL) { if p1.flags.contains(PointFlags::LEFT) { let lpos = p1.pos + p1.dmpos * woff; - contour.fill.push(Vertex::pos(lpos, 0.5, 1.0)); + triangle_fan_fill.push(Vertex::pos(lpos, 0.5, 1.0)); } else { let lpos0 = p1.pos + p0.dpos.orthogonal() * woff; let lpos1 = p1.pos + p1.dpos.orthogonal() * woff; - contour.fill.push(Vertex::pos(lpos0, 0.5, 1.0)); - contour.fill.push(Vertex::pos(lpos1, 0.5, 1.0)); + triangle_fan_fill.push(Vertex::pos(lpos0, 0.5, 1.0)); + triangle_fan_fill.push(Vertex::pos(lpos1, 0.5, 1.0)); } } else { - contour.fill.push(Vertex::pos(p1.pos + p1.dmpos * woff, 0.5, 1.0)); + triangle_fan_fill.push(Vertex::pos(p1.pos + p1.dmpos * woff, 0.5, 1.0)); } } } else { let points = &self.points[contour.point_range.clone()]; for point in points { - contour.fill.push(Vertex::pos(point.pos, 0.5, 1.0)); + triangle_fan_fill.push(Vertex::pos(point.pos, 0.5, 1.0)); } } + // convert fill triangle fan to triangles, to eliminate requirement for GL_TRIANGLE_FAN + // from the renderer. + if triangle_fan_fill.len() > 2 { + let center = triangle_fan_fill[0]; + let tail = &triangle_fan_fill[1..]; + contour.fill = tail + .windows(2) + .flat_map(|vertices| IntoIterator::into_iter([center, vertices[0], vertices[1]])) + .collect(); + } + if has_fringe { let rw = fringe_width - woff; let ru = 1.0; @@ -864,25 +878,29 @@ impl PathCache { } let vertices = &self.contours[0].fill; - if vertices.len() != 4 { + if vertices.len() != 6 { return None; } - let maybe_top_left = vertices[0]; - let maybe_bottom_left = vertices[1]; - let maybe_bottom_right = vertices[2]; - let maybe_top_right = vertices[3]; - - if maybe_top_left.x == maybe_bottom_left.x - && maybe_top_left.y == maybe_top_right.y - && maybe_bottom_right.x == maybe_top_right.x - && maybe_bottom_right.y == maybe_bottom_left.y + let maybe_t1_top_left = vertices[0]; + let maybe_t1_bottom_left = vertices[1]; + let maybe_t1_bottom_right = vertices[2]; + let maybe_t2_top_left = vertices[3]; + let maybe_t2_bottom_right = vertices[4]; + let maybe_t2_top_right = vertices[5]; + + if maybe_t1_top_left == maybe_t2_top_left + && maybe_t1_bottom_right == maybe_t2_bottom_right + && maybe_t1_top_left.x == maybe_t1_bottom_left.x + && maybe_t1_top_left.y == maybe_t2_top_right.y + && maybe_t1_bottom_right.x == maybe_t2_top_right.x + && maybe_t2_bottom_right.y == maybe_t1_bottom_left.y { Some(crate::Rect::new( - maybe_top_left.x, - maybe_top_left.y, - maybe_top_right.x - maybe_top_left.x, - maybe_bottom_left.y - maybe_top_left.y, + maybe_t1_top_left.x, + maybe_t1_top_left.y, + maybe_t2_top_right.x - maybe_t1_top_left.x, + maybe_t1_bottom_left.y - maybe_t1_top_left.y, )) } else { None diff --git a/src/renderer/opengl.rs b/src/renderer/opengl.rs index ae04ea99..7b1cfb15 100644 --- a/src/renderer/opengl.rs +++ b/src/renderer/opengl.rs @@ -263,7 +263,7 @@ impl OpenGl { for drawable in &cmd.drawables { if let Some((start, count)) = drawable.fill_verts { unsafe { - self.context.draw_arrays(glow::TRIANGLE_FAN, start as i32, count as i32); + self.context.draw_arrays(glow::TRIANGLES, start as i32, count as i32); } } @@ -306,7 +306,7 @@ impl OpenGl { for drawable in &cmd.drawables { if let Some((start, count)) = drawable.fill_verts { unsafe { - self.context.draw_arrays(glow::TRIANGLE_FAN, start as i32, count as i32); + self.context.draw_arrays(glow::TRIANGLES, start as i32, count as i32); } } }