Add a fast AABB check to the rect clipper
This commit is contained in:
parent
4c5e351829
commit
d08ff40cdf
|
@ -404,10 +404,9 @@ impl ContourRectClipper {
|
|||
}
|
||||
|
||||
pub(crate) fn clip(mut self) -> Contour {
|
||||
// TODO(pcwalton): Reenable this optimization.
|
||||
/*if self.clip_rect.contains_rect(&self.contour.bounds()) {
|
||||
if self.clip_rect.contains_rect(&self.contour.bounds()) {
|
||||
return self.contour
|
||||
}*/
|
||||
}
|
||||
|
||||
self.clip_against(AxisAlignedEdge::Left(self.clip_rect.origin.x));
|
||||
self.clip_against(AxisAlignedEdge::Top(self.clip_rect.origin.y));
|
||||
|
|
|
@ -57,6 +57,7 @@ impl Outline {
|
|||
{
|
||||
let mut outline = Outline::new();
|
||||
let mut current_contour = Contour::new();
|
||||
let mut bounds = None;
|
||||
|
||||
for segment in segments {
|
||||
if segment.flags.contains(SegmentFlags::FIRST_IN_SUBPATH) {
|
||||
|
@ -70,7 +71,9 @@ impl Outline {
|
|||
|
||||
if segment.flags.contains(SegmentFlags::CLOSES_SUBPATH) {
|
||||
if !current_contour.is_empty() {
|
||||
outline.push_contour(mem::replace(&mut current_contour, Contour::new()));
|
||||
let contour = mem::replace(&mut current_contour, Contour::new());
|
||||
contour.update_bounds(&mut bounds);
|
||||
outline.contours.push(contour);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -90,7 +93,12 @@ impl Outline {
|
|||
}
|
||||
|
||||
if !current_contour.is_empty() {
|
||||
outline.push_contour(current_contour);
|
||||
current_contour.update_bounds(&mut bounds);
|
||||
outline.contours.push(current_contour);
|
||||
}
|
||||
|
||||
if let Some(bounds) = bounds {
|
||||
outline.bounds = bounds;
|
||||
}
|
||||
|
||||
outline
|
||||
|
@ -108,42 +116,47 @@ impl Outline {
|
|||
|
||||
#[inline]
|
||||
pub fn transform(&mut self, transform: &Transform2DF32) {
|
||||
self.contours.iter_mut().for_each(|contour| contour.transform(transform));
|
||||
self.bounds = transform.transform_rect(&self.bounds);
|
||||
let mut new_bounds = None;
|
||||
for contour in &mut self.contours {
|
||||
contour.transform(transform);
|
||||
contour.update_bounds(&mut new_bounds);
|
||||
}
|
||||
self.bounds = new_bounds.unwrap_or_else(|| Rect::zero());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn apply_perspective(&mut self, perspective: &Perspective) {
|
||||
self.contours.iter_mut().for_each(|contour| contour.apply_perspective(perspective));
|
||||
self.bounds = perspective.transform_rect(&self.bounds);
|
||||
let mut new_bounds = None;
|
||||
for contour in &mut self.contours {
|
||||
contour.apply_perspective(perspective);
|
||||
contour.update_bounds(&mut new_bounds);
|
||||
}
|
||||
self.bounds = new_bounds.unwrap_or_else(|| Rect::zero());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn push_contour(&mut self, contour: Contour) {
|
||||
if self.contours.is_empty() {
|
||||
self.bounds = contour.bounds;
|
||||
} else {
|
||||
self.bounds = self.bounds.union(&contour.bounds);
|
||||
}
|
||||
self.contours.push(contour);
|
||||
}
|
||||
|
||||
pub fn clip_against_polygon(&mut self, clip_polygon: &[Point2DF32]) {
|
||||
let mut new_bounds = None;
|
||||
for contour in mem::replace(&mut self.contours, vec![]) {
|
||||
let contour = ContourPolygonClipper::new(clip_polygon, contour).clip();
|
||||
if !contour.is_empty() {
|
||||
self.push_contour(contour);
|
||||
contour.update_bounds(&mut new_bounds);
|
||||
self.contours.push(contour);
|
||||
}
|
||||
}
|
||||
self.bounds = new_bounds.unwrap_or_else(|| Rect::zero());
|
||||
}
|
||||
|
||||
pub fn clip_against_rect(&mut self, clip_rect: &Rect<f32>) {
|
||||
let mut new_bounds = None;
|
||||
for contour in mem::replace(&mut self.contours, vec![]) {
|
||||
let contour = ContourRectClipper::new(clip_rect, contour).clip();
|
||||
if !contour.is_empty() {
|
||||
self.push_contour(contour);
|
||||
contour.update_bounds(&mut new_bounds);
|
||||
self.contours.push(contour);
|
||||
}
|
||||
}
|
||||
self.bounds = new_bounds.unwrap_or_else(|| Rect::zero());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,6 +350,13 @@ impl Contour {
|
|||
self.push_segment(segment);
|
||||
}
|
||||
}
|
||||
|
||||
fn update_bounds(&self, bounds: &mut Option<Rect<f32>>) {
|
||||
*bounds = Some(match *bounds {
|
||||
None => self.bounds,
|
||||
Some(bounds) => bounds.union(&self.bounds),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Contour {
|
||||
|
|
Loading…
Reference in New Issue