Bug 268757 - [Patch] Constant DPI in PDF backend results in incorrect size of pages on screen
Summary: [Patch] Constant DPI in PDF backend results in incorrect size of pages on screen
Status: RESOLVED FIXED
Alias: None
Product: okular
Classification: Applications
Component: PDF backend (show other bugs)
Version: unspecified
Platform: Gentoo Packages Linux
: NOR normal
Target Milestone: ---
Assignee: Okular developers
URL:
Keywords:
: 264652 297941 300210 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-03-17 17:04 UTC by Eugene Shalygin
Modified: 2014-01-13 00:41 UTC (History)
7 users (show)

See Also:
Latest Commit:
Version Fixed In: 4.13.0


Attachments
Path to fix page size in Okular (2.95 KB, patch)
2011-03-17 17:04 UTC, Eugene Shalygin
Details
The patch, updated to apply on current master (2.82 KB, patch)
2011-09-08 13:50 UTC, Eugene Shalygin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Eugene Shalygin 2011-03-17 17:04:44 UTC
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
Comment 1 Eugene Shalygin 2011-03-17 17:13:15 UTC
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."
Comment 2 Albert Astals Cid 2011-03-17 17:28:14 UTC
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
Comment 3 Albert Astals Cid 2011-03-17 17:28:44 UTC
Do you have access to a multihead system? because most of okular developers have not
Comment 4 Eugene Shalygin 2011-03-17 17:53:21 UTC
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.
Comment 5 Albert Astals Cid 2011-05-08 18:02:47 UTC
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?
Comment 6 Eugene Shalygin 2011-05-08 20:49:10 UTC
Yes, it should. Sounds strange that you see incorrect size. Is X server DPI setted up correctly (i.e. results of Utils::realDpi[XY]())?
Comment 7 Eugene Shalygin 2011-05-08 20:51:03 UTC
Just checked with KDE 4.6.3 - it works as expected.
Comment 8 Eugene Shalygin 2011-09-08 13:50:09 UTC
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?
Comment 9 Albert Astals Cid 2011-09-08 15:14:24 UTC
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?
Comment 10 Albert Astals Cid 2012-04-12 16:21:52 UTC
*** Bug 297941 has been marked as a duplicate of this bug. ***
Comment 11 Albert Astals Cid 2012-05-21 17:18:20 UTC
*** Bug 300210 has been marked as a duplicate of this bug. ***
Comment 12 Eugene Shalygin 2012-08-23 09:13:19 UTC
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.
Comment 13 Albert Astals Cid 2012-08-27 19:54:24 UTC
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?
Comment 14 Eugene Shalygin 2012-08-27 20:12:32 UTC
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?
Comment 15 Albert Astals Cid 2012-08-29 18:21:45 UTC
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.
Comment 16 Albert Astals Cid 2012-09-24 07:59:46 UTC
*** Bug 264652 has been marked as a duplicate of this bug. ***
Comment 17 Eugene Shalygin 2013-07-30 13:11:28 UTC
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?
Comment 18 Albert Astals Cid 2013-07-30 18:05:57 UTC
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?
Comment 19 Eugene Shalygin 2013-07-30 19:25:54 UTC
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?
Comment 20 Albert Astals Cid 2013-07-30 21:13:49 UTC
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
Comment 21 Eugene Shalygin 2013-08-01 02:14:40 UTC
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.
Comment 22 Albert Astals Cid 2014-01-13 00:41:19 UTC
Will be fixed in 4.13.0. All thank Eugene Shalygin for his work.