In Win81+ non-dpi aware process, figure out scale factor - winapi

I'm having an issue in that I am coding for a non-dpi aware process, until a bug fix lands.
So for now I need to do a work around. My thought is this: figure out the scale up factor, and give my elements width/height scaled down by that much.
So right now I am drawing a canvas that is full width and height of second monitor, it s 1920 x 1080 (WxH). But visuaully (as measured by photoshop after screenshot) it is coming out to be 2880 x 1620. This is a scale up factor of 1.5 (2880 divided by 1920 or 1620 divided by 1080).
I tried getting dpi with methods of GetDeviceCaps and EnumDisplaysettings but all of them returned that of the primary monitor (note: EnumDisplaySettings sets dmLogPixels which I think is DPI to 0 if I do EnumDisplaySettings with constnat of ENUM_REGISTRY_SETTINGS so I had to use ENUM_CURRENT_SETTINGS).
The only method i found that returns differently is GetDpiForMonitor with MONITOR_DPI_TYPE constnat of MDT_Angular_DPI or MDT_Raw_DPI, if I use MDT_Effective_DPI it gives that of the primary monitor.
So now this is my results of running GetDpiForMonitor:
None of the secondary values divided by the primary are giving me a scale up factor 1.5. Is there anyway to get this scale factor?
Thanks

I just had an idea nad it works I am getting the scaled height/width with any of the three methods outlined in my question here: Improper width and height for second monitor from GetMonitorInfo and GetDeviceCaps
GetDeviceCaps on hdcScreen or
GetMonitorInfo or
EnumDisplayMonitors
Then I divide it by the width/height from EnumDisplaySettings.
This is the only way I found how, is there any other way? Can the experts please verify.

Related

It´s necessary to create different screens sizes and density xmls for an app? Best approach for this

Just a straight forward question. I´m trying to make the best possible choice here and there is too much information for a "semi-beginner" like me.
Well, at this point, I´m trying with screen size values for my layout (activity_main.xml (normal, large, small)) and with different densities (xhdpi, xxhdpi, mhdpi) and, if a can say so myself, it is a mess. Do I have to create every possible option to support all screen sizes and densities? Or am I doing something really wrong here? what is the best approach for this?
My layouts are now activity_main(normal_land_xxhdpi) and I have serious doubts about it.
I´m using last version of android studio of course. My app is a single activity with buttons, textview and others. Does not have any fragments or intents whatsoever, and for that reason I think this has to be an easy task, but not for me.
Hope you guys can help. I don't think i need to put any code here, but if needed, i can add it.
If you want to make a responsive UI for every device you need to learn about some things first:
-Difference between PX, DP:
https://developer.android.com/training/multiscreen/screendensities
Here you can understand that dp is a standard measure which android uses to calculate how much pixels, lets say a line, should have to keep the proportions between different screensizes with different densities.
-Resolution, Density and Ratio:
The resolution is how much pixels a screen has over height and width. This pixels can be smaller or bigger, so for instance, if you have a screen A with 10x10 px whose pixels are two times smaller than other screen B with 10 x 10 pixels too, A is two times smaller than B even when both have 10 x 10 px.
For that reason exists the meaning Density, which is how much pixels your screen has for every inch, so you can measure the quality of a screen where most pixels per inch (ppi) is better.
Ratio tells you how much pixels are for height as well as width, for example the ratio of a screen of 1000 x 2000 px is 1:2, a full hd screen of 1920 x 1080 is 16:9 (16 pixels height for every 9 pixels width). A 1:1 ratio is a square screen.
-Standard device's resolutions
You can find the most common measurements on...
https://material.io/resources/devices/
When making a UI, you use the DP measurements. You will realize that even when resolution between screens are different, the DP is the same cause they have different densities.
Now, the right way is going with constraint layout using dp measures to put your views on screen, with correct constraints the content will adapt to other screen sizes
Anyway, you will need to make additional XML for some cases:
-Different orientation
-Different ratio
-Different DP resolution (not px)
For every activity, you need to provide a portrait and landscape design. If other device has different ratio, maybe you will need to adjust the height or width due to the proportions of the screens aren't the same. Finally, even if the ratio is the same, the DP resolution could be different, maybe you designed an activity for a 640x360dp and other device has 853x480dp, which means you will have more vertical space.
You can read more here:
https://developer.android.com/training/multiscreen/screensizes
And learn how to use constraintLayout correctly:
https://developer.android.com/training/constraint-layout?hl=es-419
Note:
Maybe it seems to be so much work for every activity, but you make the first design and then you just need to copy the design to other xml with some qualifiers and change the dp values to adjust the views as you wants (without making from scratch) which is really faster.

How to set DPI in cairographics?

When creating vector graphics for PDFs, I use one of the "create" functions for PDF rendering, for instance cairo_pdf_surface_create_for_stream. The signature of that function is:
cairo_surface_t * cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func,
void *closure,
double width_in_points,
double height_in_points);
Now, I can set the size of the surface in points, but the size of one point is seemingly hardcoded. in the description it says:
width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
As you can see, 1pt = 1/72" (72 dpi). But how do I change that setting?
I could factor something into the size, when using a different resolution and compensate that way, but this seems to me like worst practice ever.
A point is a standard typograpical unit of measure. Whether or not you're talking about Cairo, a point is simply 1/72". It's not some setting you change, just like the fact that you don't change the number of inches in a foot.
The whole reason for using a physical measurement (points) instead of a screen-dependent one (pixels) is resolution-independence. This is a Good Thing.
What are you hoping to accomplish by changing the DPI?
If by "change the dpi" you want to draw at a different scale than 1/72" you can use cairo_scale(). If you are referring to the dpi of fallback images (regions that are rasterized becasue they can not be drawn natively by pdf) use cairo_surface_set_fallback_resolution().

Calculating pixel length of an image

May I know what are the ways to calculate the length of 1 pixel in centimeters? The images that I have are 640x480. I would like to compare 2 pixels at different places on the image and find the difference in distance. Thus I would need to find out what's the length of the pixel in centimeters.
Thank you.
A pixel is a relative unit of measure, it does not have an absolute size.
Edit. With regard to your edit: again, you can only calculate the distance between two pixels in an image in pixels, not in centimeters. As a simple example, think video projectors: if you project, say, a 3×3px image onto a wall, the distance between the leftmost and the rightmost pixels could be anything from a few millimeters to several meters. If you moved the projector closer to the wall or farther away from it, the pixel size would change, and whatever distance you had calculated earlier would become wrong.
Same goes for computer monitors and other devices (as Johannes Rössel has explained in his answer). There, the pixel size in centimeters depends on factors such as the physical resolution of the screen, the resolution of the graphical interface, and the zooming factor at which the image is displayed.
A pixel does not have a fixed physical size, by definition. It is simply the smallest addressable unit of picture, however large or small.
This is fully dependent on the screen resolution and screen size:
pixel width = width of monitor viewable area / number of horizontal pixels
pixel height = height of monitor viewable area / number of vertical pixels
Actually, the answer depends on where exactly your real-world units are.
It comes down to dpi (dots per inch) which is the number of image pixels along a length of 2.54 cm. That's the resolution of an image or a target device (printer, screen, &c.).
Image files usually have a resolution embedded within them which specifies their real-world size. It doesn't alter their pixel dimensions, it just says how large they are if printed or how large a “100 %” view on a display would be.
Then there is the resolution of your screen, as others have mentioned, as well as the specified resolution your graphical interface uses (usually 96 dpi, sometimes 120)—and then it's all a matter of whether programs actually honor that setting ...
The OS will assume some dpi (usually 96 dpi on windows) however the screens real dpi will depend on the physical size of the display and the resolution
e.g a 15" monitor should have a 12" width so depending on the horizontal resolution you will get a different horizontal dpi, assuming a 1152 pixel screen width you will genuinely get 96 dpi

What is a good maximum content area width for web pages?

Is there a standard max for the width of the main content area of a web page? I want to maximize screen real estate without affecting usability. I've seen a lot of sites stick to 980px or less. Anyone have any suggestions?
Target either the 800x600 or 1024x768 resolution.
For 800x600 it is around 750px.
For 1024x768 it would be 970px.
I'm assuming you're referring to the wrapper width since you mentioned 980.
The most ideal solution is to not think of pixels at all and instead rely on ems/%s and scaling, be as fluid as possible so your design fits on small mobile devices and your elements heights are not fixed but auto. Example being: http://www.456bereastreet.com/
But if you're stuck with web designers who still think pixel and you know for sure you'll be unable to get them to try making images that are liquid/fluid, I would say shoot for 960 pixels in width so you have enough viewing area in a 1024x768 with scrollbars in IE6/XP, but this really depends on your audience and the majority of your audience's screen resolutions.
Research, such as that referenced here suggests that people have a more difficult time reading long lines of text. That's why I restrict my content width to 800px or so.
You have to first ask the question. Who is my audience?
There's no "standard", especially in this age of PDAs/smartphones/netbooks/smartbooks/kiosks/etc... - while it may sound cliche, the best thing is to design a fluid layout not depending on exact screen size.
The answer may change depending on your intended/anticipated user base, of course (e.g. assume 1024 px screen width leaving you with 980 working px - and consciously decide that you are not interested in supporting anyone with smaller screen resolution).
Another solution is to allow size layout customization by making it into portal-like with user having control of layout of the portlets (ala My Yahoo).
960 is a pretty common standard, and the rationale behind that figure is the fact that fitting on a 1024 pixel wide screen will allow a big majority of your users to see the content without scrolling. See here for one of 100's of sites that give access to browser & user system capabilities statistics for some initial inspiration.
But in the end, it'll up to you to understand the structure of your customer base - if your site targets iPhones, targetting 1024 pixel wide screens may not be your smartest decision.
Not sure about absolute pixel values, but one thing I'd make sure of is that the text columns don't get too wide. There is a number of characters beyond which reading comprehension is impaired.
1000 pixels in width, is what I use which fits into the minimum 1024x768 resolution used these days without a horizontal scroller at the bottom of your browser ....

What scaling factor to use for mapping the Font size on a high resolution monitor?

We have a requirement where our application needs to support high resolution monitors. Currently, when the application comes up in High res monitor, the text that it displays is too small. We use Arial 12 point font by default.
Now to make the text visible, I need to change the font size proportionally. I am finding it tough to come up with a formula which would give me the target font size given the monitor resolution.
Here is my understanding of the problem.
1) On windows, by default 96 pixels correpond to 1 Logical inch. This means that when the monitor resolution increases, the screen size in logical inches also increase.
2) 1 Point font is 1/72 of a Logical Inch. So combined with the fact that there are 96 Pixels per Logical inch, it turns out that, there are 96/72 Pixels per Point of Font.
This means that for a 12 point font, The number of Pixels it will occupy is 12*96/72 = 16 Pixels.
Now I need to know the scaling factor by which I need to increase these Number of Pixels so that the resultant Font is properly visible. If I know the scaled pixel count, I can get the Font size simply by dividing it by (96/72)
What is the suggested scaling factor which would ensure properly scaled Fonts on all monitor resolutions?
Also, please correct if my understanding is wrong.
There's an example on the MSDN page for LOGFONT structure. Your understanding is correct, you need to scale the point size by vertres / 72.
lfHeight = -PointSize * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
If you set the resolution in Windows to match that of the physical monitor, no adjustment should be needed. Any well written program will do the multiplication and division necessary to scale the font properly, and in the newest versions of Windows the OS will lie about the resolution and scale the fonts automatically.
If you wish to handle this outside of the Windows settings, simply multiply your font size by your actual DPI and divide by 96.
Edit: Beginning with Windows Vista, Windows will not report your actual configured DPI unless you write a DPI-aware program. Microsoft has some guidance on the subject. You might find that the default scaling that Microsoft provides for non-DPI-aware programs is good enough for your purposes.

Resources