snowie2000 / mactype

Better font rendering for Windows.
https://mactype.net
GNU General Public License v3.0
10.03k stars 442 forks source link

125% scaling blurry compared to 125% custom scaling #709

Open taprobane99 opened 3 years ago

taprobane99 commented 3 years ago

Hi,

I noticed that text, particularly in older apps, is more blurry when chosing the drop-down menu 125% scaling vs going to custom scaling page and typing 125%, followed by logging out and then back in.

Some of this may be compatibility issues, but is there an explanation for this? Perhaps it's to do with the order in which freetype renders text and when the scaling takes place, perhaps upsampling instead of downsampling?

I'm not really sure of what windows is doing differently in the two scaling methods either.

(this isn't really an issue, just a curiosity)

snowie2000 commented 3 years ago

There are two different types of scaling, one is called XP style scaling and the other is called virtual scaling. With XP style scaling, an application is not scaled by system. Instead, it knows which DPI it is working on and scale itself if possible or stay unchanged which will, in turn, make the app look smaller on a high DPI monitor but without any blurry.

The virtual scaling (which is the default scaling method after win vista) on the other hand cheats the application with a virtual DPI. Any application that doesn't announce itself as DPI awared will be given a fake DPI of 96 (100% scaling) so that the application can run as intended off-screen. Then the Windows DWM composes the off-screen form image and zooms it to the real DPI. Because it's an image zooming, everything will inevitably become blurred.

HelgeBoehme commented 3 years ago

Windows 10 offers 3 methods of hiDPI scaling:

I noticed, that the last variant doesn't work with MacType, it is rendered the same as the 2nd variant (application graphics and text blurred).

ghost commented 3 years ago

MacType makes system scaling look ugly in fractional scaled HiDPI. How about adding an option to disable MacType for system scaling?

snowie2000 commented 3 years ago

MacType makes system scaling look ugly in fractional scaled HiDPI. How about adding an option to disable MacType for system scaling?

Windows looks ugly with fractional scaling.

If you prefer the original system looking, just disable mactype. Why do you want a separate option to do it?

ghost commented 3 years ago

MacType makes system scaling look ugly in fractional scaled HiDPI. How about adding an option to disable MacType for system scaling?

Windows looks ugly with fractional scaling.

If you prefer the original system looking, just disable mactype. Why do you want a separate option to do it?

When the DPI scaling setting is set to System (Advanced), the visibility is improved in legacy programs that do not support HiDPI. However, when I use MacType with this, the visibility is not improved. Fonts are just rendered at 100% scale.

ghost commented 3 years ago

100% without MacType: scale-1x

150% with custom DPI scaling settings and without MacType: scale-1.5x

100% with MacType (Default): scale-1x-mactype

150% with custom DPI scaling settings and MacType (Default): scale-1.5x-mactype

snowie2000 commented 3 years ago

I see. I worked through a bunch of GDI API and a lot of articles about the Windows 10 GDI scaling, but there seems to be no way to detect if a DC is been scaling up or getting the scaling factor.

So, you have to disable MacType for apps manually until someone contributes the code to recognize it.

sammilucia commented 3 years ago

Also this looks like Excel. Most versions of Office use their own don't rendering (it's not GDI or Direct write)

ghost commented 3 years ago

Also this looks like Excel. Most versions of Office use their own don't rendering (it's not GDI or Direct write)

What is their own? Do you mean Office has font rendering engine itself?

snowie2000 commented 3 years ago

Also this looks like Excel. Most versions of Office use their own don't rendering (it's not GDI or Direct write)

Word and onenote are using DirectWrite while excel is still using GDI. The reason the word looks so awful is that it's grayscale.

ghost commented 3 years ago

It's hard to perfectly detect if the DC is upscaling, but we can make an estimate.

#include <winuser.h>
#include <shellscalingapi.h>

// ...

PROCESS_DPI_AWARENESS awareness;
GetProcessDpiAwareness(proc, &awareness);

if (awareness == PROCESS_DPI_UNAWARE) {
    HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
    UINT axis_x, axis_y;

    GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &axis_x, &axis_y);

    if ((axis_x > 96 || axis_y > 96) && g_disable_if_upscaling) {
        // Do not apply mactype for that process
    }
}
snowie2000 commented 3 years ago

I don't if your code snippet works for the dc upscaling, but there are at least two problems.

  1. Mactype has no way to get window handles. All it can get are DCs.

  2. Mactray can get window handles, but the injection timing is way ahead of any windows creation. So there is no way to check for dpi awareness on mactype initialization.

ghost commented 3 years ago

I don't if your code snippet works for the dc upscaling, but there are at least two problems.

  1. Mactype has no way to get window handles. All it can get are DCs.

  2. Mactray can get window handles, but the injection timing is way ahead of any windows creation. So there is no way to check for dpi awareness on mactype initialization.

So all it can get is DC, mactype can be disabled per process, not per HWND.

snowie2000 commented 3 years ago

I don't if your code snippet works for the dc upscaling, but there are at least two problems.

  1. Mactype has no way to get window handles. All it can get are DCs.

  2. Mactray can get window handles, but the injection timing is way ahead of any windows creation. So there is no way to check for dpi awareness on mactype initialization.

So all it can get is DC, mactype can be disabled per process, not per HWND.

Yes, mactype operates on dc level.

Mactype itself can only be disable or enabled on process level but it can always fallback to windows gdi on any circumstances, per dc or even per character.

ghost commented 3 years ago

I found the way to check if GDI DPI scaling is enabled.

If the registry value contains GDIDPISCALING in following keys, GDI scaling is enabled.

HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers HKLM\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

Or check whether the program is included in the EnableGdiDPIScaling registry value.

HKCU\Software\Policies\Microsoft\Windows\Display HKLM\Software\Policies\Microsoft\Windows\Display

For example:

Windows Registry Editor Version 5.00

[HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files\\CPUID\\HWMonitor\\HWMonitor.exe"="~ GDIDPISCALING DPIUNAWARE"
snowie2000 commented 3 years ago

That is also the only way I could think of. Thanks for your suggestion and I'll keep looking for new possibilities.

ghost commented 3 years ago

Application manifests can also contain GDI DPI scaling settings but in low priority compared to above. See here.

Thanks for looking my suggestions!