lcnr/crow

support HiDPI fractional scaling

lcnr opened this issue ยท 12 comments

lcnr commented

extracted from #4,

We currently panic in case dpi is not a whole number.

How is this going? on Manjaro and i can't launch the engine because of this.

lcnr commented

Don't quite know how to test this myself as my computer does not support it.
I am also unsure on what exactly is the expected behavior there.

  • round dpi to the nearest integer (doesn't work nicely as we now either have an empty section of the window or part of the image is invisible)
  • somehow use anti aliasing (which kind of defeats why I made this).

In case you have the time to both help me test this and tell me about your desired outcome, I might be able to do something here.

Hmm you could send me some examples and i can send you the results, or maybe add both these things but let the user pick one.

lcnr commented

The easiest way to test this would be clone this repo and remove these three lines:

crow/src/backend/mod.rs

Lines 135 to 137 in 12af842

} else if dpi.fract().min(1.0 - dpi.fract()) > std::f64::EPSILON {
bug!("fractional HiDPI scaling is not yet supported: {}", dpi);
}

You should then be able to run cargo run --example <example name (e.g. rectangles)> --release.

Adding AA will be kind of a mess so I would first like to see if the first approach works.

This seems fine
Screenshot_20200416_091825
Screenshot_20200416_092002

(its running on a 1440p screen)
Screenshot_20200416_092157

lcnr commented

hmm, does look ok I guess. What's your DPI? I can replace the bug with a warning for now I guess ๐Ÿค”

fractional HiDPI scaling is not yet supported: 1.5 <---
Should that not be the almost worst case as in the furthest from a whole int.

lcnr commented

It is the worst case ๐Ÿ˜† It doesn't seem like I have an example that requires the whole screen though.

Will look into this more later ๐Ÿ‘

IDK how github works,
but would it not be better to just do:
if dpi < 0.5 {
bug!("unexpected dpi: {}", dpi);
} else if dpi.fract().min(1.0 - dpi.fract()) > std::f64::EPSILON {
println!("fractional HiDPI scaling is not yet supported. but may work! (dpi: {})", dpi);
}

I have some data for the devs:

Panic

     Running `target\debug\crowtest.exe`
thread 'main' panicked at 'fractional HiDPI scaling is not yet supported: 1.25

    This might be a bug, consider filing an issue at https://github.com/lcnr/crow/issues/new', C:\Users\rkleb\.cargo\registry\src\github.com-1ecc6299db9ec823\crow-0.7.1\src\backend\mod.rs:136:13
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\/library\std\src\panicking.rs:515
   1: std::panicking::begin_panic_fmt
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\/library\std\src\panicking.rs:457
   2: crow::backend::Backend::initialize<tuple$<> >
             at C:\Users\rkleb\.cargo\registry\src\github.com-1ecc6299db9ec823\crow-0.7.1\src\backend\mod.rs:136
   3: crow::Context::new<tuple$<> >
             at C:\Users\rkleb\.cargo\registry\src\github.com-1ecc6299db9ec823\crow-0.7.1\src\context.rs:37
   4: crowtest::main
             at .\src\main.rs:34
   5: core::ops::function::FnOnce::call_once<enum$<core::result::Result<tuple$<>,enum$<crow::error::Error> >, 0, 3, Err> (*)(),tuple$<> >  
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\library\core\src\ops\function.rs:227
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: process didn't exit successfully: `target\debug\crowtest.exe` (exit code: 101)

cargo --version --verbose

cargo 1.55.0 (32da73ab1 2021-08-23)
release: 1.55.0
commit-hash: 32da73ab19417aa89686e1d85c1440b72fdf877d
commit-date: 2021-08-23

My Code:

use crow::{
    glutin::{
        event::{Event, WindowEvent},
        event_loop::{ControlFlow, EventLoop},
        window::WindowBuilder,
    },
    Context, 
    DrawConfig,
    Texture,
    NewTextureError,
    image::{
        self,
        ImageFormat,
    }
};
use std::path::Path;
use asefile::AsepriteFile;

trait FromAseprite{
    fn from_ase(ctx: &mut Context, path: &Path) -> Result<Texture, NewTextureError>;
}

impl FromAseprite for Texture{
    fn from_ase(ctx: &mut Context, path: &Path) -> Result<Texture, NewTextureError> {
        let ase = AsepriteFile::read_file(path).unwrap();
        let img = ase.frame(0).image();

        Texture::from_image(ctx, img)
    }
}

fn main() -> Result<(), crow::Error> {
    let event_loop = EventLoop::new();
    let mut ctx = Context::new(WindowBuilder::new(), &event_loop)?;

    let texture = Texture::from_ase(&mut ctx, Path::new("./data/graphics/player.aseprite"))?;

    event_loop.run(
        move |event: Event<()>, _window_target: _, control_flow: &mut ControlFlow| match event {
            Event::WindowEvent {
                event: WindowEvent::CloseRequested,
                ..
            } => *control_flow = ControlFlow::Exit,
            Event::MainEventsCleared => ctx.window().request_redraw(),
            Event::RedrawRequested(_) => {
                let mut surface = ctx.surface();
                ctx.clear_color(&mut surface, (0.4, 0.4, 0.8, 1.0));
                ctx.draw(&mut surface, &texture, (100, 150), &DrawConfig::default());
                ctx.present(surface).unwrap();
            }
            _ => (),
        },
    )
}
lcnr commented

forgot to actually publish a new version of this crate, published version 0.7.2 now