emilk / egui

egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native
https://www.egui.rs/
Apache License 2.0
22.44k stars 1.6k forks source link

Porting egui to ereaders. Issue with text sizes after update from 13.1 to 27.2 #4456

Open Szybet opened 6 months ago

Szybet commented 6 months ago

Discussed in https://github.com/emilk/egui/discussions/4440

Originally posted by **Szybet** May 1, 2024 Hello I'm trying to port egui to eink devices using [FBInk](https://github.com/NiLuJe/FBInk) as the backend. Based on [this](https://github.com/asimaranov/egui_pocketbook) I was able to achieve some good results: ![image](https://github.com/emilk/egui/assets/53944559/4b59450e-8b02-4606-8832-ce86e17c8a46) The issue I was having was the small UI size as you can see. I decided to update egui from 13.1 to 27.2 and now text sizes are not calculated: ``` [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "File" at pos [10.0 11.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[0.0 0.0] - [0.0 0.0]] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "Side Panel" at pos [8.0 26.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[0.0 0.0] - [0.0 0.0]] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "Write something: " at pos [8.0 38.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[0.0 0.0] - [0.0 0.0]] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "Hello World!" at pos [20.0 38.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[0.0 0.0] - [0.0 0.0]] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "Increment" at pos [12.0 59.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[0.0 0.0] - [0.0 0.0]] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "https://github.com/emilk/egui/" at pos [100.0 1022.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[-0.0 0.0] - [0.0 0.0]] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "egui template" at pos [208.0 32.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[0.0 0.0] - [0.0 0.0]] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "https://github.com/emilk/egui_template" at pos [208.0 35.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[0.0 0.0] - [0.0 0.0]] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] Printing out string: "Source code." at pos [208.0 38.0] with size [0.0 0.0] [2024-05-01T07:18:58Z DEBUG egui_fbink::backend] galley rect: [[0.0 0.0] - [0.0 0.0]] ``` The code is [here](https://github.com/Quill-OS/egui-fbink/blob/main/src/backend.rs), the logs are from [here](https://github.com/Quill-OS/egui-fbink/blob/10d92989ed8e520c5cc40a195ed5bd8397196a9c/src/backend.rs#L210-L261) and calling of next egui frames is [here](https://github.com/Quill-OS/egui-fbink/blob/10d92989ed8e520c5cc40a195ed5bd8397196a9c/src/backend.rs#L264-L307). The example app is [here](https://github.com/Quill-OS/egui-fbink/tree/main/example/src) but it shouldn't matter. Thanks!
YgorSouza commented 6 months ago

With regular eframe apps, this happens if you don't have any fonts, i.e., you don't enable the default_fonts feature and you don't add any fonts of your own. But this feature is enabled by default, so you should have it in your repo, so I'm not sure if this is the problem in your case. Also, you have a dependency on epi, but it looks like this crate has been moved into eframe. If you look in your lockfile, you have a dependency on egui 0.17 because of epi, it is not going to work with egui 0.27. Maybe you could check out the projected listed in https://github.com/emilk/egui#3rd-party-integrations to see how integrations are supposed to work in the current version. Eventually you could add yours to the list as well, once you get this sorted out.

Szybet commented 6 months ago

Bingo, fonts were missing... somehow. A warning that they are missing would be helpful... Adding fonts only fixes the galley data missing, the text is still too small:

Well anyway, I dropped epi (why was it nowhere stated that it was dropped?) and moved to eframe. Now I'm using the most recent egui for sure. The text sizes are still small and I can't change them, the pixel_per_point value is ignored for fonts. Only the background rect changes. As for the 3rd party integrations, I did looked into them and everything magically works there ;/

I also needed to include x11 integration for winit because it needs a platform to even compile. For my use case, winit could be optional

YgorSouza commented 6 months ago

So if you zoom the UI, (for example by calling ui.ctx().set_zoom_factor(ui.input(|i| i.time as f32 * 0.05).sin() + 1.0); in the example code), the text size doesn't change? The Shape variant's doc does say it needs to be recreated:

https://github.com/emilk/egui/blob/ded8dbd45bc8616475c364878f6b8e2f7293d12c/crates/epaint/src/shape.rs#L50-L53

But I don't know at what level this is supposed to be done in the integration.

Szybet commented 6 months ago

Well this does seem to do something. Is it really the solution? to call the zoom factor? I need to clean up and refine the code properly for this to work properly, but it does something, even if it's a work around it's something, thanks

Idk about the text shape thing

YgorSouza commented 6 months ago

I think the integration crate just has to pass the correct native_pixels_per_point to egui (otherwise the text might look blurry as mentioned here), and then each application can set the zoom factor and/or the text_styles so it displays well on the target screen. Maybe the default style isn't appropriate for e-readers, so you could provide a different default that looks better.

Szybet commented 6 months ago

I decided zoom is the solution because text_styles will only affect text

Sadly, setting zoom affects the ui only for one frame. In Context::set_zoom_factor is a variable used named new_zoom_factor. In this function if I remove the if statement if ctx.memory.options.zoom_factor != zoom_factor { the zoom factor works fine (well I still need to set the zoom factor up every frame). What is here going on?

The only thing I'm aware of doing wrong is this:

How do I create a eframe::Frame? info storage from that struct are private and I need this struct for App::update. For now I just edited the library directly, but this requires doing that on every library download

but Frame doesn't contain any meaningful information for this issue

YgorSouza commented 6 months ago

The zoom factor change should be permanent. If you make this change to the hello_world example, the zoom changes to 200% when you click the button and then stays that way:

M examples/hello_world/src/main.rs
@@ -46,6 +46,7 @@ impl eframe::App for MyApp {
             });
             ui.add(egui::Slider::new(&mut self.age, 0..=120).text("age"));
             if ui.button("Increment").clicked() {
+                ui.ctx().set_zoom_factor(2.0);
                 self.age += 1;
             }
             ui.label(format!("Hello '{}', age {}", self.name, self.age));

So maybe your integration is using a new Context every frame? And about the Frame, I don't think integrations are supposed to depend on eframe at all. The other integrations don't (though some of them depend on egui-winit or egui-wgpu). Maybe you should just copy what you need from eframe instead of depending on it.

Szybet commented 6 months ago

I don't have input yet so this example won't work. Setting zoom factor anywhere: once, every frame, only on first frame does the same thing

And no, I don't create a new context every frame