What does the "zoom factor" mean in OLECMDID_OPTICAL_ZOOM? - zooming

I am using ExecWB() to zoom in/out my WebBrowser control like this:
m_lpBrowser->ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &(CComVariant)zoomFactor, NULL);
This works just fine when my OS dpi is 100% (96 dpi). However, under OS dpi 150% (144 dpi), setting zoom factor as 100 makes the web page in the browser look much smaller.(I was expecting to get exactly the same layout as the one under OS dpi 100%)
Then I found an old IE8 document.
In this document, OLECMDID_OPTICAL_ZOOM is said to be setting the ZOOM FACTOR of the browser
( ZOOM FACTOR = System DPI / Layout DPI)
But I just can't figure out the meaning of Layout DPI. Is this the root cause that I get smaller web pages?

This MSDN document mentioned there is a flag DOCHOSTUIFLAG_DPI_AWARE controlling the High DPI behaviour of the web control.
When the flag is set during initialization, the web control uses IE8 High DPI behavior; otherwise, it uses IE7 High DPI behaviour by default.
Under IE8 High DPI behaviour, the parameter zoom factor means exactly the scaling percentage of the web page, just like what you see in the IE zoom UI.
However, under IE7 High DPI behaviour, it's a little bit more complicated. Based on my experiment result,
the actual scaling factor = zoom factor / system dpi(%)
For example, under system 120dpi(125%), setting zoom factor 125 result in 1.0x scaling of web pages.
However, there is still something I can't explain: under system 120dpi(125%), I was expecting to get 80% scaling of web pages when I set zoom factor of 100. It turns out that words are 80% of their original size, but the pictures still 100%. Perhaps it is a bug in IE7 zooming.

Related

How to Emulate High Res displays for Web layout issues

I have website which is having layout issues on certain devices which I believe I've tracked down to high res displays which also have the display scaling in windows 10 set to 200%. (not 200% in the browser, but in the display settings in the Windows Control Panel)
The problem is I don't have a device which can duplicate the resolution of these devices, which is 2736 x 1824 (it's a MS Surface Pro). Oh yeah, this only happen with Edge...
I know of sites which have VMs which will run different browsers for testing purposes, but I don't know of any which allow you to choose your resolution. Without going out and getting a hold of this specific machine, how else can I debug this issue?
You could create a custom device in the developer console, and simply display it at whatever scale actually fits on your screen. For instance, create a custom device with that particular resolution, then in the developer console on Chrome you can view it scaled down 50% (if your own resolution is 1920x1080) so that the whole thing is visible.
Turned out none of the emulation/scaling options in the dev console would emulate what was really happening. I ended up remoting into the customer's computer so I could do my own debugging on there and resolved the issue.
Seems like Edge v 44 was computing some CSS calc function for a div height incorrectly (off by 1 or 2 pixels) which was making some divs push out and mess up the layout.
The fix was to tweak the CSS so the calculation wasn't required.

DevicePixelRatio appears to be suddenly stacking with windows scale

I have recently added DPI scaling to a project to ensure the UI elements in the project (drawn with canvas) are a reasonably consistent size across devices. This seemed to work at first, but a day after adding the code, I am suddenly getting massive UI elements on my 4k laptop. My high DPI mobile device and normal DPI desktop monitor display at the intended size. What puzzles me is that on the night I implemented window.devicePixelRatio, the value that was being output was "1". But now today, the value is "2.5" and I havent changed any settings.
The machine is running Windows and is set to %250 scale by default and has been since I got the laptop, if I set it to %100, the DPI output returns to "1". This isn't very helpful as everything is then tiny, including the UI Element. All of this also applies to changing the page zoom.
The problem ultimately seems to be that scales are being applied twice, so for a desired scalar of n, I get n^2 instead. I suspect the problem lies below the browser level because all browsers on this machine (Chrome, Opera, Edge, IE) display the same over inflated UI elements.
I need to figure out how to to get my computer back to the state where the master display setting is set to %250 but window.devicePixelRatio returns a value of "1". I would also really like to know why this changed in the first place so I can avoid it in the future.

font-size on 2K and higher resolution devices

I have a screen with resolution 1680 x 1050.
I work as a web developer and while building websites, we use font-sizes that are easily readable on laptops with resolutions ranging between 1366 x 768 to 1920 x 1080.
While using Chrome developer tools, I chose Amazon Kindle Fire HDX which has resolution of 2560 x 1600. On this device (which chrome is simulating), the font-size renders very small due to high-res. I tried many font-size units such as vw, vh, % so that the font-size appears same on all resolutions but failed.
I even opened StackOverflow using Chrom Dev Tool and saw the font-size appearing to be too small. I don't know if the font size that appears on the real Kindle HDX is the same as what I'm seeing on Kindle HDX that chrome is simulating and I don't have a real 2K res device to test my websites as well. How to counter this issue? I want my websites to be readable on all resolutions.
If your font sizes are in relative units then you are likely just fine.
I think what you are seeing in Chrome Dev Tools is the "Zoom to fit" feature that will zoom the page of the targeted device to fit your browser window. Uncheck "Zoom to fit" and I think you will see the text is legible. And take notice that the ruler values will change to be more accurate representation as well.
You can see in this screenshot that the rulers indicate that the device simulation is being rendered at 1600px wide even though this screenshot was definitely not taken at 1600px wide. It was zoomed to fit my window.
I suggest you use em as the unit for fonts to make it more cross-browser/device compatible. em should work off the browser's own built-in font sizes to make things more readable as well as the browser's zoom settings.
Also, you may want to try out various CSS frameworks that may try to handle more consistent cross-browser/device consistency to keep fonts at more relative sizes according to device/dpi settings. (Unfortunately, I haven't experience in this scenario, but should be a good place to start your research).

Webgl Distortion in Chrome with three Monitors

I'm developing a webgl application (a simple solar system) and everything looks fine on Chrome and Firefox on ONE monitor
But if I start eyefinity (three monitors each full hd + bezel compensation) the solarsystem is distorted in chrome.
In Firefox it looks correct and really nice:
http://kritten.org/pictures/firefox.jpg
In Chrome it looks like this:
http://kritten.org/pictures/chrome.jpg
It seems that the principal point (is this the right name?) is in the wrong location.
If I move forward in Firefox I actually move forward, but in Chrome I move to the right. So it keeps this distortion any time.
Are there any ideas what could be wrong?
The issue with Chrome is it's got a limit on the size a canvas can be. This is part of the WebGL spec although arguably Chrome should fix it. You can try to encourage them to fix it here.
The specific issue is that the WebGL spec says that even though you may ask for a canvas of a certain size WebGL might give you a smaller drawingbuffer. This was specifically because graphics cards have a size limit. Some are as low as 1024. Let's say some card has a limit of 2048. You've got one monitor that's 1280x1024. No problem.
You now add a second monitor for a total desktop space of 2560x1024. You now stretch a window across both monitors. You ask for a canvas of size 2560x1024. What should happen? WebGL can't make one that big, the GPU says it has a limit of 2048. So there were 3 option
Crash. That's no go
Force the canvas to stay under 2048
Let the canvas be stretched to 2560 but make the drawingbuffer the limit which is 2048 in this example
The WebGL committee picked #3 because it's the one least likely to cause problems. The worst that happens is you get a distorted image but the user can scale the window back down until things are normal so your webpage doesn't die.
Unfortunately 99.99% of WebGL programs ignore this feature of WebGL and so you get this distorted image when you run into that part of the spec.
In this particular case though the limit isn't in your GPU it's in Chrome. The proof is that it works in Firefox. Again you can try to encourage them to fix it here.
If you'd like to make your program work around it you need to look up what size the canvas's drawing buffer was actually made and use that in the correct places. You can find out but checking gl.drawingBufferWidth and gl.drawingBufferHeight
That means first set the camera aspect to the size the canvas is actually displayed. You really should always do this
aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
perspective = yourPerspectiveFunction(fov, aspect, zNear, zFar);
In three.js that would be
camera.aspect = renderer.domElement.clientWidth /
renderer.domElement.clientHeight;
camera.updateProjectionMatrix();
You should set your viewport to the size of the drawingbuffer
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawBufferHeight);
In three.js that would be
renderer.setViewport(0, 0, renderer.context.drawingBufferWidth,
renderer.context.drawingBufferHeight);
That should also always work.
If you're doing anything else related to the width and height of the canvas (picking, scissor, etc..) you'll need to do the appropriate math to convert from the size the canvas is being displayed to the size of its drawingbuffer
That will get rid of the distortion, of course since Chrome will actually only be creating a smaller drawingBuffer you'll get some scaling.

How to maintain responsiveness on mobiles with Bootstrap?

(Started over my question because people downvoted and locked it because I didn't add pictures ... so here we go, since I got the answer from other sites, and this is actually important to large scale responsive sites, I also provide the answer)
I am trying to overcome the pixel density (real vs hardware) of viewports, that basically breaks/collapses Bootstrap sites even on huge tablets just because they have huge resolutions (alas, they default to a huge zoom, which causes bootstrap to collapse the content even though it would fit).
Here, Bootstrap own site, Desired effect:
But, instead, even on devices with higher resolution, I get this:
The reason is the viewport standard, that "enforces" a zoom according to dpi to prevent sites rendering too small (example: a 12px font on a 400dpi device would be almost unreadable). However, I would like to let the user decide if he wants to zoom or not, and not be constrained to the hardcoded zoom (example, my xperia Zq with 1920px have a hardcoded 220% zoom, leaving less than 900px of viewport, which will collapse bootstrap out of responsive mode).
Tips?
As per the specification of the viewport (which is still a draft but most certainly will become a standard soon, reference can be found here: https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag), if you set a fixed value to the viewport width, that does not mean the viewport will have THAT width, but that the viewport should have AT LEAST that width. So, for instance, if I set the viewport to 1000px, than the viewport WILL be enlarged to that size, causing a smaller zoom, and also causing bootstrap not to collapse.
As per the specification, if the device cannot enlarge the viewport to the requested size, it will enlarge to the maximum possible size (alas, the real pixel width of the device), but will still enforce a zoom, probably causing the collapse.
So, the solution to prevent the collapse on a site that can handle a screen, say, 768px (Bootstrap's definition of tablet), is:
<meta name="viewport" content="width=768, initial-scale=1">
This will prevent the collapse if the device have 768 or more real pixels, while collapsing otherwise, thus the site will show just like it would on a desktop if there is enough rooms.
why do that?(a.k.a. pros)
The mobile version on such high dpi devices will look like the desktop version and won't collapse even though it clearly can handle the site
The responsiveness will remain on those devices, instead of auto-collapse whatever mobile it is due to the high viewport constrains (often above 200% zoom), you are only changing the default "start zoomed" to "start unzoomed"
why not? (a.k.a. cons)
By reducing or disabling the zoom effect of the viewport, fonts and other components will render on "real size", which on a high dpi device might be too small (like a 12px font on a 400dpi is almost unreadable) - yet, the user still has the freedom do zoom in, which will cause the site to collapse as needed just like if you resize a window on the desktop version. This solution, therefore, does not break anything, just change the default behavior.
On really small but high DPI devices, this is still annoying since you will have to zoom every time, so the size you specify should really be the SMALLER possible size, and not just, say, force the device real pixel count and totally disable zoom