iced icon indicating copy to clipboard operation
iced copied to clipboard

Incorrect line rendering with very sharp angles

Open edwloef opened this issue 1 year ago • 2 comments

Is your issue REALLY a bug?

  • [X] My issue is indeed a bug!
  • [X] I am not crazy! I will not fill out this form just to ask a question or request a feature. Pinky promise.

Is there an existing issue for this?

  • [X] I have searched the existing issues.

Is this issue related to iced?

  • [X] My hardware is compatible and my graphics drivers are up-to-date.

What happened?

In the following code example, the second path is rendered incorrectly:

struct State;

#[derive(Debug)]
enum Message {}

impl State {
    fn new() -> Self {
        Self
    }

    fn update(&mut self, _: Message) {}

    fn view(&self) -> iced::Element<'_, Message> {
        iced::Element::from(
            iced::widget::Canvas::new(self)
                .width(iced::Length::Fill)
                .height(iced::Length::Fill),
        )
    }
}

impl Default for State {
    fn default() -> Self {
        Self::new()
    }
}

impl iced::widget::canvas::Program<Message> for State {
    type State = ();

    fn draw(
        &self,
        _state: &Self::State,
        renderer: &iced::Renderer,
        theme: &iced::Theme,
        bounds: iced::Rectangle,
        _cursor: iced::mouse::Cursor,
    ) -> Vec<iced::widget::canvas::Geometry> {
        let mut frame = iced::widget::canvas::Frame::new(renderer, bounds.size());

        let path1 = iced::widget::canvas::Path::new(|path| {
            path.line_to(iced::Point::new(100.0, 100.0));
            path.line_to(iced::Point::new(100.0, 200.0));
        });
        frame.stroke(
            &path1,
            iced::widget::canvas::Stroke::default().with_color(theme.palette().text),
        );

        let path2 = iced::widget::canvas::Path::new(|path| {
            path.line_to(iced::Point::new(200.0, 100.0));
            path.line_to(iced::Point::new(200.0, 200.0));
            path.line_to(iced::Point::new(201.0, 100.0));
        });
        frame.stroke(
            &path2,
            iced::widget::canvas::Stroke::default().with_color(theme.palette().text),
        );

        vec![frame.into_geometry()]
    }
}

fn main() -> iced::Result {
    iced::application("", State::update, State::view).run()
}

image

This occurs on both the crates.io release and the master branch.

What is the expected behavior?

The right path shouldn't be cut off higher than the left path.

Version

master

Operating System

Linux

Do you have any log output?

No response

edwloef avatar Sep 04 '24 11:09 edwloef

Additional info: this only occurs with the wgpu backend. Using tiny-skia results in the lines rendering as expected.

edwloef avatar Sep 05 '24 13:09 edwloef

Even more additional info: this is probably down to floating-point precision. The output of the following code snippet illustrates that:

        let path1 = iced::widget::canvas::Path::new(|path| {
            path.line_to(iced::Point::new(200.0, 100.0));
            path.line_to(iced::Point::new(200.0, 200.0));
            path.line_to(iced::Point::new(201.00004, 100.0));
        });
        frame.stroke(
            &path1,
            iced::widget::canvas::Stroke::default().with_color(theme.palette().text),
        );

        let path2 = iced::widget::canvas::Path::new(|path| {
            path.line_to(iced::Point::new(200.0, 300.0));
            path.line_to(iced::Point::new(200.0, 400.0));
            path.line_to(iced::Point::new(201.00003, 300.0));
        });
        frame.stroke(
            &path2,
            iced::widget::canvas::Stroke::default().with_color(theme.palette().text),
        );

this code snippet also creates some interesting results:

        let path2 = iced::widget::canvas::Path::new(|path| {
            path.line_to(iced::Point::new(200.0, 400.0));
            path.line_to(iced::Point::new(200.0, 600.0));
            path.line_to(iced::Point::new(202.0, 400.0));
        });
        frame.stroke(
            &path2,
            iced::widget::canvas::Stroke::default().with_color(theme.palette().text),
        );

edwloef avatar Sep 05 '24 16:09 edwloef

i seem to be having a similar issue to this where my line segments will not display randomly.... How can i change the backend to test if this is the same issue?

Gibbz avatar Jan 29 '25 02:01 Gibbz

i seem to be having a similar issue to this where my line segments will not display randomly.... How can i change the backend to test if this is the same issue?

ICED_BACKEND=tiny_skia cargo run --release

airstrike avatar Jan 29 '25 03:01 airstrike

Ok thanks. The issue I'm having is this one https://github.com/iced-rs/iced/issues/2281

Gibbz avatar Jan 29 '25 04:01 Gibbz