Fix boundary condition for active edges precisely on tile boundaries

This commit is contained in:
Patrick Walton 2019-01-29 19:29:42 -08:00
parent 13716fd733
commit 6b8848bb35
2 changed files with 15 additions and 8 deletions

View File

@ -115,6 +115,7 @@ impl BuiltObject {
// TODO(pcwalton): SIMD-ify `tile_x` and `tile_y`.
fn add_fill(&mut self, segment: &LineSegmentF32, tile_x: i16, tile_y: i16) {
//println!("add_fill({:?} ({}, {}))", segment, tile_x, tile_y);
let mut segment = (segment.0 * F32x4::splat(256.0)).to_i32x4();
let tile_origin_x = (TILE_WIDTH as i32) * 256 * (tile_x as i32);
@ -143,11 +144,14 @@ impl BuiltObject {
// Cull degenerate fills.
if (px.0 & 0xf) as u8 == ((px.0 >> 8) & 0xf) as u8 &&
(subpx.0 & 0xff) as u8 == ((subpx.0 >> 16) & 0xff) as u8 {
//println!("... ... culling!");
return;
}
let tile_index = self.tile_coords_to_index(tile_x, tile_y);
//println!("... ... OK, pushing");
self.fills.push(FillObjectPrimitive {
px,
subpx,
@ -175,13 +179,12 @@ impl BuiltObject {
LineSegmentF32::new(&right, &left)
};
/*
println!("... emitting active fill {} -> {} winding {} @ tile {}",
/*println!("... emitting active fill {} -> {} winding {} @ tile {},{}",
left.x(),
right.x(),
winding,
tile_x);
*/
tile_x,
tile_y);*/
while winding != 0 {
self.add_fill(&segment, tile_x, tile_y);

View File

@ -18,7 +18,6 @@ use pathfinder_geometry::outline::{Contour, Outline, PointIndex};
use pathfinder_geometry::point::Point2DF32;
use pathfinder_geometry::segment::Segment;
use pathfinder_geometry::util;
use smallvec::SmallVec;
use std::cmp::Ordering;
use std::mem;
@ -92,9 +91,14 @@ impl<'o, 'z> Tiler<'o, 'z> {
// Add new active edges.
let strip_max_y = ((i32::from(strip_origin_y) + 1) * TILE_HEIGHT as i32) as f32;
while let Some(queued_endpoint) = self.point_queue.peek() {
if queued_endpoint.y >= strip_max_y {
// We're done when we see an endpoint that belongs to the next tile.
//
// Note that this test must be `>`, not `>=`, in order to make sure we don't miss
// active edges that lie precisely on the tile boundary.
if queued_endpoint.y > strip_max_y {
break;
}
self.add_new_active_edge(strip_origin_y);
}
}
@ -121,8 +125,8 @@ impl<'o, 'z> Tiler<'o, 'z> {
let mut last_segment_x = -9999.0;
let tile_top = (i32::from(tile_y) * TILE_HEIGHT as i32) as f32;
/*println!("---------- tile y {}({}) ----------", tile_y, tile_top);
println!("old active edges: {:#?}", self.old_active_edges);*/
//println!("---------- tile y {}({}) ----------", tile_y, tile_top);
//println!("old active edges: {:#?}", self.old_active_edges);
for mut active_edge in self.old_active_edges.drain(..) {
// Determine x-intercept and winding.