Font not evenly sized with scaled displays #47

Closed
opened 1 year ago by cherti · 7 comments
cherti commented 1 year ago

Tested in: sway

When displays are scaled in sway to have the same effictive DPI, foot is not rendering fonts evenly sized over all displays.

Screen-arrangement in sway:
output eDP-1 pos 0 1130 res 2560x1440 scale 1.77
output DP-3 pos 1446 717 res 2560x1440

font=font:style=Regular:size=10
Result: Font on eDP-1 noticably bigger than on DP-3
DP-3: https://p.nnev.de/9508
eDP-1: https://p.nnev.de/9509

font=font:style=Regular:size=10:dpi=120
Result: Font on eDP-1 noticably smaller than on DP-3
DP-3: https://p.nnev.de/9511
eDP-1: https://p.nnev.de/9510

font=font:style=Regular:pixelsize=10
Result: Font on eDP-1 noticably smaller than on DP-3
DP-3: https://p.nnev.de/9513
eDP-1: https://p.nnev.de/9512

font=font:style=Regular:pixelsize=10:dpi=120
Result: Font on eDP-1 noticably smaller than on DP-3
DP-3: https://p.nnev.de/9515
eDP-1: https://p.nnev.de/9514

Tested in: sway When displays are scaled in sway to have the same effictive DPI, foot is not rendering fonts evenly sized over all displays. Screen-arrangement in sway: output eDP-1 pos 0 1130 res 2560x1440 scale 1.77 output DP-3 pos 1446 717 res 2560x1440 font=font:style=Regular:size=10 Result: Font on eDP-1 noticably bigger than on DP-3 DP-3: https://p.nnev.de/9508 eDP-1: https://p.nnev.de/9509 font=font:style=Regular:size=10:dpi=120 Result: Font on eDP-1 noticably smaller than on DP-3 DP-3: https://p.nnev.de/9511 eDP-1: https://p.nnev.de/9510 font=font:style=Regular:pixelsize=10 Result: Font on eDP-1 noticably smaller than on DP-3 DP-3: https://p.nnev.de/9513 eDP-1: https://p.nnev.de/9512 font=font:style=Regular:pixelsize=10:dpi=120 Result: Font on eDP-1 noticably smaller than on DP-3 DP-3: https://p.nnev.de/9515 eDP-1: https://p.nnev.de/9514
dnkl commented 1 year ago
Owner

Tested in: sway

Which version? And which version of wlroots?

font=font:style=Regular:size=10

Let's work with this configuration. It is the one that should work.

I'd like to establish a base line. What does it look like if you configure both monitors to use a scale factor of 1? Are the fonts exactly the same size (and I encourage you to use a ruler;) )? If not, is the difference about the same as with the 1.77 scale factor? What are the pixelsize values in the foot log (feel free to post all log output)?

If you change the scale factor of one monitor to 2, does it still look the same as with a scale factor of 1?

> Tested in: sway Which version? And which version of wlroots? > font=font:style=Regular:size=10 Let's work with this configuration. It is the one that _should_ work. I'd like to establish a base line. What does it look like if you configure both monitors to use a scale factor of 1? Are the fonts exactly the same size (and I encourage you to use a ruler;) )? If not, is the difference about the same as with the 1.77 scale factor? What are the pixelsize values in the foot log (feel free to post all log output)? If you change the scale factor of one monitor to 2, does it still look the same as with a scale factor of 1?
Poster

sway is built from git in revision r6362.9b5895be (somewhere between 1.4 and 1.5).
wlroots is built from git in revision 0.10.0.r136.g2988ebb6.

I have tested things with the third screen as well.
Resolutions see here: https://p.nnev.de/9517

I observe, with size=50 letter sizes to consistently be (over all scaling combinations I've tested, including the one I'm using in prod):
eDP-1: 2cm
DP-3: 2.3cm
DP-4: 3.3cm

So apparently I have to correct my assumption, DPI detection seems to (somewhat) work independent on scaling level, but the lettersize is still different on every screen.

With size=10 the differences between eDP-1 and DP-3 are just 6mm vs. 5mm (the same fraction between 2. and 2, so that's consistent), which is slim, but still noticable.

On the third screen I initially hadn't tested we go full teleprompter-mode, though (3.3cm for 50 and 8mm for 10).

All scale 1:
log eDP-1: https://p.nnev.de/9518
log DP-3: https://p.nnev.de/9519

eDP-1 scaled 2, DP-3 scaled 1:
log eDP-1: https://p.nnev.de/9520
log DP-3: https://p.nnev.de/9521

sway is built from git in revision `r6362.9b5895be` (somewhere between 1.4 and 1.5). wlroots is built from git in revision `0.10.0.r136.g2988ebb6`. I have tested things with the third screen as well. Resolutions see here: https://p.nnev.de/9517 I observe, with size=50 letter sizes to consistently be (over all scaling combinations I've tested, including the one I'm using in prod): eDP-1: 2cm DP-3: 2.3cm DP-4: 3.3cm So apparently I have to correct my assumption, DPI detection seems to (somewhat) work independent on scaling level, but the lettersize is still different on every screen. With size=10 the differences between eDP-1 and DP-3 are just 6mm vs. 5mm (the same fraction between 2. and 2, so that's consistent), which is slim, but still noticable. On the third screen I initially hadn't tested we go full teleprompter-mode, though (3.3cm for 50 and 8mm for 10). All scale 1: log eDP-1: https://p.nnev.de/9518 log DP-3: https://p.nnev.de/9519 eDP-1 scaled 2, DP-3 scaled 1: log eDP-1: https://p.nnev.de/9520 log DP-3: https://p.nnev.de/9521
dnkl commented 1 year ago
Owner

Thanks! And thank you for being so thorough!

I've tested things on my three monitors I have available at home: one 4K "hiDPI" screen and two laptop screens.

Instead of just comparing them against each other, I calculated how large the font where supposed to be. The definition of one (font) point is 1/72 inch. Thus, if you set a point size of 72pt, you should get a 1 inch font. I used 85pt, which should be very very close to 3cm.

Using an unpatched foot, the results where pretty close on the 4K screen, but a bit off on the laptop screens. Still, not as much off as yours.

Then I tried changing which DPI value we pass to FontConfig. Previously, we passed the vertical PPI value. I changed that to insted pass the diagonal PPI.

I then ran echo -e '\e[7mtest\e[m' and measured the cell height. Using \e[7m inverts the colors, making it easy to measure. Note that the cell height is expected to be slightly larger than the font.

With that, I get the following results:

For the 4K screen: DP-3: 3840x2160+0x0@60Hz PHL 276E8V 27.15" scale=1 PPI=166x166 (physical) PPI=166x166 (logical), DPI=162.27, the cell height was 3.10cm.

The first laptop: eDP-1: 1920x1080+0x0@60Hz 0x42ED 15.33" scale=1 PPI=147x154 (physical) PPI=147x154 (logical), DPI=143.66, the cell height was 3.15cm.

And the pinebook pro: eDP-1: 1920x1080+0x0@60Hz <Unknown> 13.96" scale=1 PPI=160x180 (physical) PPI=160x180 (logical), DPI=157.78, the cell height was 3.15cm.

I think that is as close as one can expect to get. The only way to get closer would be to manually measure the screen dimensions and override the EDID. Not sure how to do that in Sway, or if it is even possible.

I'll put up a PR that I hope you can test.

I have also been searching for a definition of FontConfig's dpi property, to see what exactly you're supposed to set it to, but haven't been able to find anything.

If using the diagonal DPI value still procudes results that are way off, we could also try using the horizontal PPI. If that doesn't work, we can look at the dimension values reported by your monitors to see if they are bad.

Finally, I'd suggest trying with scale factor == 1, at least first. Especially the 0.8 factor looked like it might have triggered a Sway/wlroots bug; the logical PPI values reported by foot did not look sane.

Thanks! And thank you for being so thorough! I've tested things on my three monitors I have available at home: one 4K "hiDPI" screen and two laptop screens. Instead of _just_ comparing them against each other, I calculated how large the font where _supposed_ to be. The definition of one (font) point is 1/72 inch. Thus, if you set a point size of 72pt, you should get a 1 inch font. I used 85pt, which should be very very close to 3cm. Using an unpatched foot, the results where pretty close on the 4K screen, but a bit off on the laptop screens. Still, not as much off as yours. Then I tried changing _which_ DPI value we pass to FontConfig. Previously, we passed the **vertical** PPI value. I changed that to insted pass the **diagonal** PPI. I then ran `echo -e '\e[7mtest\e[m'` and measured the **cell** height. Using `\e[7m` inverts the colors, making it easy to measure. Note that the cell height is expected to be slightly larger than the font. With that, I get the following results: For the 4K screen: `DP-3: 3840x2160+0x0@60Hz PHL 276E8V 27.15" scale=1 PPI=166x166 (physical) PPI=166x166 (logical), DPI=162.27`, the cell height was 3.10cm. The first laptop: `eDP-1: 1920x1080+0x0@60Hz 0x42ED 15.33" scale=1 PPI=147x154 (physical) PPI=147x154 (logical), DPI=143.66`, the cell height was 3.15cm. And the pinebook pro: `eDP-1: 1920x1080+0x0@60Hz <Unknown> 13.96" scale=1 PPI=160x180 (physical) PPI=160x180 (logical), DPI=157.78`, the cell height was 3.15cm. I think that is as close as one can expect to get. The only way to get closer would be to manually measure the screen dimensions and override the EDID. Not sure how to do that in Sway, or if it is even possible. I'll put up a PR that I hope you can test. I have also been searching for a definition of FontConfig's `dpi` property, to see what exactly you're supposed to set it to, but haven't been able to find anything. If using the diagonal DPI value still procudes results that are way off, we could also try using the horizontal PPI. If _that_ doesn't work, we can look at the dimension values reported by your monitors to see if they are bad. Finally, I'd suggest trying with scale factor == 1, at least first. Especially the 0.8 factor looked like it might have triggered a Sway/wlroots bug; the logical PPI values reported by foot did not look sane.
dnkl commented 1 year ago
Owner

To speed things up, here's a patch you can apply on top off #48. It will log the monitor's physical size (which foot uses to calculate the PPI).

You can then compare that with what you get if you measure with a ruler.

--- a/wayland.c
+++ b/wayland.c
@@ -1037,11 +1037,13 @@ wayl_init(const struct config *conf, struct fdm *fdm)
 
     tll_foreach(wayl->monitors, it) {
         LOG_INFO(
-            "%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d PPI=%dx%d (physical) PPI=%dx%d (logical), DPI=%.2f",
+            "%s: %dx%d+%dx%d@%dHz %s %.2f\" (%dx%dmm) scale=%d "
+            "PPI=%dx%d (physical) PPI=%dx%d (logical), DPI=%.2f",
             it->item.name, it->item.dim.px_real.width, it->item.dim.px_real.height,
             it->item.x, it->item.y, (int)round(it->item.refresh),
             it->item.model != NULL ? it->item.model : it->item.description,
-            it->item.inch, it->item.scale,
+            it->item.inch, it->item.dim.mm.width, it->item.dim.mm.height,
+            it->item.scale,
             it->item.ppi.real.x, it->item.ppi.real.y,
             it->item.ppi.scaled.x, it->item.ppi.scaled.y,
             it->item.dpi);
To speed things up, here's a patch you can apply on top off https://codeberg.org/dnkl/foot/pulls/48. It will log the monitor's physical size (which foot uses to calculate the PPI). You can then compare that with what you get if you measure with a ruler. ```diff --- a/wayland.c +++ b/wayland.c @@ -1037,11 +1037,13 @@ wayl_init(const struct config *conf, struct fdm *fdm) tll_foreach(wayl->monitors, it) { LOG_INFO( - "%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d PPI=%dx%d (physical) PPI=%dx%d (logical), DPI=%.2f", + "%s: %dx%d+%dx%d@%dHz %s %.2f\" (%dx%dmm) scale=%d " + "PPI=%dx%d (physical) PPI=%dx%d (logical), DPI=%.2f", it->item.name, it->item.dim.px_real.width, it->item.dim.px_real.height, it->item.x, it->item.y, (int)round(it->item.refresh), it->item.model != NULL ? it->item.model : it->item.description, - it->item.inch, it->item.scale, + it->item.inch, it->item.dim.mm.width, it->item.dim.mm.height, + it->item.scale, it->item.ppi.real.x, it->item.ppi.real.y, it->item.ppi.scaled.x, it->item.ppi.scaled.y, it->item.dpi); ```
Poster

the patch fails to apply for me, it should apply onto your diagonal-dpi-branch, right? Just making sure I have the right branch, then in doubt I can apply that patch by hand, it's short enough after all.^^

the patch fails to apply for me, it should apply onto your diagonal-dpi-branch, right? Just making sure I have the right branch, then in doubt I can apply that patch by hand, it's short enough after all.^^
dnkl commented 1 year ago
Owner

That was the idea yes. But yeah, if I made a mistake, just apply it by hand. The only important thing is to see the same values for the monitor's physical dimensions as foot does, i.e it->item.dimm.mm.{width,height}.

That was the idea yes. But yeah, if I made a mistake, just apply it by hand. The only important thing is to see the same values for the monitor's physical dimensions as foot does, i.e `it->item.dimm.mm.{width,height}`.
dnkl commented 1 year ago
Owner

I tested the "diagonal-dpi" branch at work, and my three monitors there went from 3.3, 3.4 and 3.4cm to all being 3.1cm.

So looks like it's an improvement.

I tested the "diagonal-dpi" branch at work, and my three monitors there went from 3.3, 3.4 and 3.4cm to all being 3.1cm. So looks like it's an improvement.
dnkl referenced this issue from a commit 1 year ago
dnkl closed this issue 1 year ago
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.