Created attachment 58122 [details] Path to fix page size in Okular Version: unspecified (using KDE 4.6.1) OS: Linux Currently, poppler generator uses fixed DPI values (72) for generating images of PDF pages. If display DPI is not equal to 72, this results in incorrect scale of pages. Since monitors with large DPI will be more and more popular, this problem will be more and more significant. This issue was fixed initially by pino (see bug #191614) but the fix lead to other problem (#204386) in dual-head X configurations. I beleive that root of the problem is that in Okular core code "Points" is used both as typographic point (unit of length) and as measure of page scale that leads to mess and cause a problem either here or there. For example, in poppler backend size of page is defined in Points, but actually it is pixels, multiplied by 72. To fix this I propose to add the "Pixels" member to Okular::Generator::PageSizeMetric enum. To address issue with dual-heads, Utils::realDPI() can be used in Poppler Generator class instead of Utils::dpi(). Proposed patch is attached. I tested it with dualhead where heads have different size (in millimeters). The pages on larger monitor is larger, of course, but the y have the width to height ratio. Reproducible: Always
Sorry, "For example, in poppler backend size of page is defined in Points, but actually it is pixels, multiplied by 72." shall be readed as "For example, in poppler backend size of page is defined in Points, but actually it is pixels, DIVIDED by 72."
Unfortunately this has problems in systems were people have multihead systems and different dpi in each screen, more info at https://bugs.kde.org/show_bug.cgi?id=204386
Do you have access to a multihead system? because most of okular developers have not
Yes, I know about bug #204386. Yes, I have dual-head system with different (in millimiters and pixels) sizes of monitors. the problem with the previous attempt was that DPI for Xinerama-enabled screens was incorrect (that of Utils::dpi()) and it caused shrinked pages in Xinerama screens. Utils::realDPI() functions returns correct DPI for Xinerama screens with two identical heads and thus it works perfect in this case. In case of heads with different sizes, I can not imaginate what to do to make image of the page on screen always equal to paper page size (consider, for example, Okular window that is half showed on one, half on another screen). If physical sizes of pixels of screens is different, I do not know what to do. So, I do not see any regression from current approach with constant DPI in Xinerama screens with proposed patch.
I just applied this patch and having 100% of zoom does not make the page in the screen be as big as an A4 in real life, isn't that what the patch is supposed to fix?
Yes, it should. Sounds strange that you see incorrect size. Is X server DPI setted up correctly (i.e. results of Utils::realDpi[XY]())?
Just checked with KDE 4.6.3 - it works as expected.
Created attachment 63508 [details] The patch, updated to apply on current master I would be happy if this patch (or something that solves the problem) would be accepted to the mainstream. Here is updated for master patch. Can we continue with it? Albert wrote that the patch does not work for him. Albert, could You, please, check that output of `xdpyinfo | grep -1 dimensions` corresponds to physical parameters of your screen?
Ok, this time seems to work, the question is, can we make this work on multiscreens with different dpi? obviously not asking if the page is half in one screen and half in other, but what if the page is totally in each of them? Can we query the dpi of that screen?
*** Bug 297941 has been marked as a duplicate of this bug. ***
*** Bug 300210 has been marked as a duplicate of this bug. ***
Excuse my long silence, please. I found a time to return to the problem. If I connect two screens with different physical DPI, nor Qt nor xdpyinfo (X itself?) does not know about real DPI. They report DPI (and size in mm) of the second connected screen to be the sames as the DPI of the first one (and size to be incorrectly calculated). However, XRandr retruns correct values. Do you want to have it solved via direct dependence on XRandr? If yes, I can try to change Okular Utils to add 1) (optional) dependency on XRandr and 2) DPI calculation for particular widget.
Hmmm, as first answer i'd say a dependency in XRandr is not cool but if you think the patch is not hard, you can give it a go and maybe once i see the patch i change my opinion? What do you think?
I agree that direct dependence on XRandr is not the best one. I would prefer to see the same dependence and proper DPI information in Qt. But I can try. Let's summarize what do we want: 1. If viewer widget is completely in one screen, use real DPI of that screen. 2. If viewer widget is displayed in more than one screen, use DPI of the main screen. When to react on widget movements? How to propagate these events to generator? Technically, rewrite Util::realDPI() is not a big problem, but what to do with these questions?
I guess the optimal for 2 is "use the DPI of the screen that contains more pixels of the window". But i guess your suggestion is a valid suggestion as first implementation. * When to react on widget movements? QWidget has a move event, that should be fine * How to propagate these events to generator? You don't, you just invalidate the current pixmaps and request new ones.
*** Bug 264652 has been marked as a duplicate of this bug. ***
Dear Albert, I would like to return to this problem and finally push it to the finish. Since physical DPI grows so quickly, the problem becomes more and more prominent. For example, my wife already refuses to use Okular because of that. I decided to use LibKScreen instead of pure XRandr (that gives a possibility to handle other desktop servers, what do you think? Is it better than XRand?). So I added screen size in millimetres to it and calculation of DPI on the base of LibKScreen data in Utils::realDpi(). However, the DPI depends on QWidget used to draw on, therefore now one needs to pass this widget into generators. As for me, the widget has to be passed in Generator::generatePixmap() call. And here I can not decide how to do that. Should it be added to PixmapRequest class? Or to the Page class? I'm afraid that I do not understand design of Okular wee enough to make this decision. Could you, please, help me?
Passing down the widget is not acceptable, you may very well not be rendering into a widget (imagine someone does a okulartoimage binary that gust renders to a .png file). Why can't you pass down the dpis in the request?
Thanks Albert! This is exectly the type of advice I was looking for. Do I understand you corretly that you suggest to add DPI into to PixmapRequest class?
Ok, second think about it. No, PixmapRequest is not the correct place since you need the dpi at loadDocument time so that the pages have the correct size. So probably you need is modify the loadDocument call to pass down the dpi. Document already has a QWidget * param in the constructor (that shouldn't be there but i'm not going to ask you to change it) so it should not be that hard, hopefully :D
Albert, thanks for advices! I've posted partial solution and remaining questions in reviewboard (https://git.reviewboard.kde.org/r/111829) . Please, take a look.
Will be fixed in 4.13.0. All thank Eugene Shalygin for his work.