diff --git a/conrod_core/src/mesh.rs b/conrod_core/src/mesh.rs index 74929a41c..74050f470 100644 --- a/conrod_core/src/mesh.rs +++ b/conrod_core/src/mesh.rs @@ -206,11 +206,15 @@ impl Mesh { let (w, h) = rect.w_h(); let left = (rect.left() * dpi_factor + half_viewport_w).round() as i32; let top = (rect.top() * dpi_factor - half_viewport_h).round().abs() as i32; - let width = (w * dpi_factor).round() as u32; - let height = (h * dpi_factor).round() as u32; - Scizzor { - top_left: [left.max(0), top.max(0)], - dimensions: [width.min(viewport_w as u32), height.min(viewport_h as u32)], + let width = ((w * dpi_factor).round() as u32).min(viewport_w as u32); + let height = ((h * dpi_factor).round() as u32).min(viewport_h as u32); + if width == 0 || height == 0 { + None + } else { + Some(Scizzor { + top_left: [left.max(0), top.max(0)], + dimensions: [width, height], + }) } }; @@ -257,7 +261,9 @@ impl Mesh { // Update the scizzor and produce a command. current_scizzor = new_scizzor; - commands.push(PreparedCommand::Scizzor(new_scizzor)); + if let Some(scizzor) = new_scizzor { + commands.push(PreparedCommand::Scizzor(scizzor)); + } // Set the state back to plain drawing. current_state = State::Plain { @@ -265,6 +271,11 @@ impl Mesh { }; } + // If the scizzor is `None`, then nothing is viewable, so don't draw anything. + if current_scizzor.is_none() { + continue; + } + match kind { render::PrimitiveKind::Rectangle { color } => { switch_to_plain_state!(); diff --git a/conrod_core/src/position/range.rs b/conrod_core/src/position/range.rs index f0ad449c9..828a55489 100644 --- a/conrod_core/src/position/range.rs +++ b/conrod_core/src/position/range.rs @@ -236,12 +236,7 @@ impl Range { /// The Range that represents the range of the overlap between two Ranges if there is some. /// - /// Note that If one end of `self` aligns exactly with the opposite end of `other`, `Some` - /// `Range` will be returned with a magnitude of `0.0`. This is useful for algorithms that - /// involve calculating the visibility of widgets, as it allows for including widgets whose - /// bounding box may be a one dimensional straight line. - /// - /// The returned `Range`'s `start` will always be <= its `end`. + /// The returned `Range`'s `start` will always be < its `end`. /// /// # Examples /// @@ -266,7 +261,7 @@ impl Range { let start = ::utils::partial_max(self.start, other.start); let end = ::utils::partial_min(self.end, other.end); let magnitude = end - start; - if magnitude >= 0.0 { + if magnitude > 0.0 { Some(Range::new(start, end)) } else { None diff --git a/conrod_core/src/render.rs b/conrod_core/src/render.rs index bd86d0bdc..0ec661f63 100644 --- a/conrod_core/src/render.rs +++ b/conrod_core/src/render.rs @@ -942,7 +942,7 @@ fn next_widget<'a>( } // We only want to return primitives that are actually visible. - let is_visible = container.rect.overlap(window_rect).is_some() + let is_visible = container.rect.overlap(scizzor).is_some() && graph::algo::cropped_area_of_widget(graph, id).is_some(); if !is_visible { continue; diff --git a/conrod_core/src/widget/primitive/line.rs b/conrod_core/src/widget/primitive/line.rs index 7f0e8b2a5..c0f673664 100644 --- a/conrod_core/src/widget/primitive/line.rs +++ b/conrod_core/src/widget/primitive/line.rs @@ -65,6 +65,8 @@ pub enum Cap { Round, } +const DEFAULT_THICKNESS: Scalar = 1.0; + impl Line { /// Build a new **Line** widget with the given style. pub fn styled(start: Point, end: Point, style: Style) -> Self { @@ -93,8 +95,9 @@ impl Line { /// The same as [**Line::abs**](./struct.Line#method.abs) but with the given style. pub fn abs_styled(start: Point, end: Point, style: Style) -> Self { - let (xy, dim) = Rect::from_corners(start, end).xy_dim(); - Line::styled(start, end, style).wh(dim).xy(xy) + let line = Line::styled(start, end, style); + let (xy, wh) = line.calc_rect().xy_dim(); + Line::styled(start, end, style).wh(wh).xy(xy) } /// Build a new **Line** and shift the location of the start and end points so that the centre @@ -112,10 +115,10 @@ impl Line { /// The same as [**Line::centred**](./struct.Line#method.centred) but with the given style. pub fn centred_styled(start: Point, end: Point, style: Style) -> Self { - let dim = Rect::from_corners(start, end).dim(); - let mut line = Line::styled(start, end, style).wh(dim); + let mut line = Line::styled(start, end, style); line.should_centre_points = true; - line + let r = line.calc_rect(); + line.wh(r.dim()) } /// The thickness or width of the Line. @@ -144,6 +147,12 @@ impl Line { self.style.set_pattern(Pattern::Dotted); self } + + fn calc_rect(&self) -> Rect { + let thickness = self.style.maybe_thickness.unwrap_or(DEFAULT_THICKNESS); + let corners = rect_corners(self.start, self.end, thickness * 0.5); + super::bounding_box_for_points(corners.iter().cloned()) + } } impl Style { @@ -241,7 +250,6 @@ impl Style { /// The width or thickness of the Line. pub fn get_thickness(&self, theme: &Theme) -> Scalar { - const DEFAULT_THICKNESS: Scalar = 1.0; self.maybe_thickness .or_else(|| { theme