Rotate/Zoom and IndirectUI in Paint.NET v4.0

In my last post I briefly mentioned that Rotate/Zoom had been converted to use IndirectUI. In the current release (v3.5.5) it is implemented with a custom WinForms dialog along with manual data binding, etc. It works fine and simply wasn’t a priority to convert in the v3.5 timeframe.

Well, here’s how it looks now:

It certainly fits in better with the rest of the UI now. The “roll ball 3D” control will also be available for plugins to use. In addition, thanks to some polite prodding by a prominent plugin author (pyrochild), I’ve added the ability to use the regular angle chooser control with a constrained range. Currently, only angle ranges of [-180, +180] and [0, +360] are permitted.

The greyed area shows the angle range that is not permitted.

I’m also planning to add the ability for IndirectUI-based effects and file type UI to use tab pages. This will be useful for having Basic/Advanced pages for file types, and to have more configurable effect properties without resorting to a “tall” UI dialog.

Anyway, that’s all for now!


May 2010 usage statistics – Windows 7 reaches 26%, overtakes Vista

Two months ago I published the usage statistics for March 2010. This month’s data shows a drop in usage for the first time (6.3%), as well as a surprising and unexplained nosedive in the Turkish usage base. I checked the web server’s 404 (“not found”) logs, and it doesn’t account for it, so I’m at a loss to explain it.

In any case, the trends that I’m the most interested in are still showing positive gains. The upward march for Windows 7 (+27.9%!) and 64-bit (+21.1%!) continues, which of course is very good news. Windows 7, at almost 26% total share, has now overtaken Windows Vista, and I’m hoping to see Windows XP fall below the 50% mark soon. I expect that to happen within the next 2 months. The percentages for both English and Russian have gone up, although this may simply be a statistical rebalancing from the mysterious Turkish falloff.

Paint.NET v4.0 is progressing steadily. I’m still in the middle of the “MQ” phase, which is a time for investing in code quality and technology upgrades (“MQ” stands for “Milestone Quality”). I’ve established a good programming model for Direct2D and DirectWrite, improved the super sampling quality for Image->Resize, converted Rotate/Zoom to use IndirectUI, and also significantly improved the way error dialogs and crash logs work.

In previous versions of Paint.NET (which includes the latest v3.5.5), a crash brings a sudden halt to the program with an unfriendly and needlessly verbose dialog:

The user then clicks OK and has no idea what to do about it. This dialog violates the principle of “users don’t read errors” (or anything, honestly, myself included!). Even if they did, it’s unlikely that the crash log would make much sense for them. In Paint.NET v4.0 this will still result in the application shutting down, but at least the UI is improved:

Further improvements may involve hooking into Windows Error Reporting (WER) so that crash logs can be uploaded to me automatically (while respecting your privacy settings, of course).

Clicking on the “Show Details” button will give access to a simple “Copy to clipboard” button and “Open crash log folder” link. The crash logs are no longer unceremoniously (and unprofessionally, I might add) dumped to the desktop. Instead, the last 20 of them are stored in the local (non-roaming) AppData directory (e.g., c:\users\UserName\AppData\Local\Paint.NET\CrashLogs). Most people won’t see that many crashes, of course, but I wanted to ensure these couldn’t gobble up an unbounded amount of disk space. The log files are also stored using NTFS compression to further reduce their disk space impact (although they’re fairly small to begin with).

A similar dialog is also used for reporting other errors. For instance, instead of displaying a nebulous “There was an unspecified error opening the file” error, Paint.NET will now tell you that there was an error (not an “unspecified” error) and let you see the .NET exception. For most situations this won’t really improve the situation, but it will greatly aid troubleshooting – on the forum we can simply ask someone to copy+paste the exception details which will help to speed things up.

Other planned improvements include an “operation restart manager” so that insufficient disk space errors (and others) can be recovered from without data loss, as well as the implementation of a “segmented list” class. The latter will help Paint.NET avoid problems with allocating larger and larger arrays for things like polygon lists (among other things). Instead, the array will be broken up into smaller chunks which a 32-bit system can deal with much more easily.

For instance, if a 200MB array needs to be allocated in a situation where sufficient memory is available but a large enough region of contiguous virtual address space isn’t, this will greatly improve the probability that the allocation will succeed. In fact, often times the problem is that a 150MB (for example) array needs to grow to 200MB, in which case a total of 350MB of memory is required to complete the operation! The SegmentedList<T> class will also avoid the overhead (CPU and memory bandwidth) of constantly copying all those blocks of data, at a cost of higher CPU usage when reading and writing to individual elements within the array. It seems to be a fair tradeoff.

Another improvement coming, one which is long overdue, is fault tolerance when saving an image. Currently, Paint.NET always overwrites the file you are saving and this can have disastrous consequences if an error is encountered in this process. The end result is a 0-byte file even for users who’ve been diligent about saving regularly. The solution is simple, involving first saving to a temporary file and then deleting the old one only when the operation has succeeded. You might ask why this wasn’t implemented a long time ago, and I’ll defer to Raymond Chen’s discussion of the Windows taskbar for an explanation.

The installer now has a hard block on having a minimum amount of memory (RAM). I’m occasionally humored with a crash log from a poor Windows XP user trying to run Paint.NET with 96MB of RAM (which is usually 128MB with a sizable chunk carved out for slow integrated graphics). Sorry, but it just isn’t going to be reliable with so little memory available!

I’ll skip the boring pie charts this month. Here’s the usual tabular data though:

March 2010 May 2010
Total update manifest hits 4,528,824 4,243,221
Hits per day 146,091 136,878
32-bit 86.89% 84.12%
64-bit 13.11% 15.88%
Windows XP 55.76% 51.20%
Windows 2003 0.24% 0.21%
Windows Vista / 2008 23.72% 22.64%
Windows 7 / 2008 R2 20.29% 25.95%
English 38.85% 39.43%
non-English 61.15% 60.57
German 14.68% 15.52%
French 7.79% 7.99%
Portuguese 5.20% 5.43%
Spanish 6.02% 5.78%
Japanese 2.24% 2.33%
Italian 3.57% 3.78%
Polish 1.51% 1.53%
Netherlands (Dutch) 1.35% 1.37%
Russian 9.79% 10.31%
Chinese (Simplified) 0.75% 0.79%
Chinese (Traditional) 0.55% 0.58%
Turkish 3.49% 0.95% ?
Korean 0.35% 0.32%
All other languages 0.81% 0.86%
Have translations 79.45% 81.38%
Don’t have translations 20.55% 18.62%

Bold indicates that Paint.NET ships with the translation. Korean had a translation in v3.36, but not in v3.5+. For Russian, the reverse is true.