Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix scizzor behaviour and errors due to flooring/rounding #1437

Merged
merged 1 commit into from
Oct 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions conrod_core/src/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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],
})
}
};

Expand Down Expand Up @@ -257,14 +261,21 @@ 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 {
start: vertices.len(),
};
}

// 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!();
Expand Down
9 changes: 2 additions & 7 deletions conrod_core/src/position/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
///
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion conrod_core/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 14 additions & 6 deletions conrod_core/src/widget/primitive/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down