Search code examples
.netwpf

WPF Vector based interface


I'm working on a new C# application using WPF. I was under the impression that WPF was vector based and that text/buttons would be drawn in a resolution independent way. When running my application it’s fairly obvious that my application isn’t being drawn using vectors. Some of the text gets fairly blocky, and when using the windows magnifying glass you can see rough edges on everything.

Is there something special I need to do in my application to turn vector drawing on? Or is something wrong with my specific machine? (I'm running Windows Vista x64 with the latest graphics drivers)


Solution

  • The Mangifier accessibility tool in Windows Vista used to be WPF aware. If you zoomed WPF content you would see a sharp magnified version of the app - demonstrating that WPF is indeed vector based.

    Tim Sneath, a technology evanglist with Microsoft, blogged about this in 2006:

    enter image description here

    6/25/2011: Original image gone. Replaced with another image showing same effect.

    Greg Schechter answers some commenters on this blog, explaining that magnifier no longer has this trick. Magnifier would specially detect WPF applications, and know how to ask them to render themselves scaled. They removed a dependancy on WPF in magnifier. It seems that magnifier had a dependancy on something in WPF that they wanted to take away or depricate:

    Both 'bp' and 'Joseph Cooney' have noticed that magnification of WPF content using the built in OS Magnifier no longer does resolution independent zoom of content.

    That observation is correct.

    As a result of a series of changes that are too numerous to describe here, the OS magnifier is no longer "WPF-aware", and does bitmap scaling just like it does of other content. Although we do lose this feature, we believe that without the dependencies that enabled Magnifier to work in a WPF-specific way, we can be more agile in what we provide to WPF customers moving forward.

    Note that the above is only about out-of-process magnification. When you do zooming (via scaling) within your own WPF application, the rendering continues to be re-rasterized at the higher scale, so everything remains smooth in that most common scenario. This change is strictly about using the external magnifier.

    So the magnifier used to have it, but no longer.


    In the the Channel 9 video "Greg Schechter: Windows Presentation Foundation(WPF) Architecture", Greg Schechter talked about how Magnifier used to provide this functionality.

    Magnifier and DWM worked together. Magnifier modified the DWM scene graph to make it's client area actually point to the desktop root of the scene graph. DWM then knew the magnifier was there and knew how to avoid that horrible "pointing a camcorder at a television showing the camcorder" effect.


    Edit: 9/7/2018. From Ian Griffiths' answer:

    Back when Vista first shipped, and when WPF was on version 3.0, zooming with the built-in magnifier would actually do vector-based scaling.

    This stopped working when WPF 3.5 service pack 1 shipped. (It worked in 3.5 before sp1.) The reason it worked before then is that the DWM (Desktop Window Manager) - the part of Windows responsible for presenting everything you see on screen - uses MILCORE.DLL to do its rendering. Version 3.0 and 3.5 of WPF also used this same component to render - this meant that all WPF content was native content, so to speak. (In fact, on Windows XP, which doesn't have the DWM, MILCORE.DLL is something that WPF puts on your system for its own benefit. But it's built into Vista and Windows 7.) When WPF was using MILCORE.DLL to render on Vista, any effects applied by the DWM such as scaling would also apply in the way you want to WPF - it really did scale without pixelating.

    Unfortunately, this is no longer the case. And the reason is that WPF started adding new rendering features. In 3.5 sp1, the new feature in question was support for custom pixel shaders. To enable that, Microsoft had to release an update to the MIL. (The Media Integration Layer - the bit that does the actual rendering.) However, they weren't really in a position to update MILCORE.DLL, because that's part of Windows - it's how everything you see on screen gets to be on screen. Releasing a new version of MILCORE.DLL effectively means pushing out an update to Windows. The release schedule for Windows is independent of that for .NET, and so the only way the WPF team could reasonably add new features was to ship a new MIL. (In theory they could have done it via Windows Update, but since WPF is now owned by a different division of Microsoft than Windows, that sort of thing doesn't seem to happen in practice.)

    As of .NET 3.5 sp1, the MIL is in a different DLL called wpf_gfx_vXXXX.dll where vXXXX is the version number. In .NET 4.0, it's wpf_gfx_v0400.dll.

    The upside is that WPF gets to add new rendering features with each new version, without needing Windows itself to be updated. The downside is that WPF's rendering is no longer as tightly integrated with Windows as it was briefly back when Vista shipped. And the upshot is, as you've seen, that magnifying is not as much fun as it used to be.