You are currently browsing the category archive for the ‘Uncategorized’ category.
I’ve blogged about system requirements before. So far I’ve been content to leave the minimum version of Windows set to XP SP2, based both on user feedback and lack of necessity. It has come at the cost of adding about 2MB to the download package, but the work had already been completed and it was useful.
However, that will have to change soon. Later this year, Paint.NET will move to .NET 4.0. I am planning to do this before the increasingly mythic release of Paint.NET v4.0, and shortly after the public release of .NET 4.0 (whenever that ends up being). If you check out the download page for Microsoft .NET Framework 4.0 Beta 2, you will see that it requires XP SP3 or Vista SP1.
For many users this won’t be an issue. The updates are free*, and if you’re lucky then they’ll be automatically applied on some nice lazy weekend when you’re out sleeping, drinking, or fishing. Maybe even all three! Although if you haven’t updated yet, then please do so soon.
Many computers’ updates, especially those within the walls of corporate environments or educational institutions, are more conservatively applied (and with good reason). For those administrators in charge of such things, consider this blog post as my request to make sure all your XP boxes are at SP3, and that all your Vista boxes are at SP1 or SP2. There will then be one less obstacle toward getting .NET 4.0 installed, and thus one step closer toward the Paint.NET update which will require it.
While the minimum for Vista users will be SP1, I still recommend SP2 of course. That will help ensure you have the latest updates and security fixes as well as allowing you to install the Platform Update which includes DirectWrite, something that Paint.NET makes good use of if available.
For your convenience, here are download links for the service packs:
You can also just open up Windows Update and have it download and install things until it’s done.
* free in the sense that Microsoft does not charge for them.
For those who just want the fix and to skip the commentary, go here.
Paint.NET v3.5.x requires a CPU with SSE support. Since SSE is a 10-year old technology, it was a pretty safe bet. I have only received one e-mail from a user who was confused about this. Oh, and a single blog comment from a gentleman who apparently believes he’ll be using the computer he bought in 2001 for a total of 20 years. That certainly is a long time to stick with XP! More power to him, but I certainly won’t be supporting XP anymore in the year 2020. Anyway …
The reason that SSE is required is for three reasons, none of which are really good enough on their own but together they were acceptable:
- DDS (DirectDraw Surface) file type support makes use of a C++ library called “Squish”. It has 3* optimization levels that can be chosen at compile time: normal, SSE, and SSE2. Enabling SSE for 32-bit systems was shown to yield a very large performance improvement. For 64-bit systems, enabling SSE2 is a no-brainer because all x64 CPUs support it.
- I wanted to cut down on the number of native DLLs that I had to dispatch out to, which would reduce the surface area of code that I was liable to maintain. Put simply: fewer code configurations means fewer bugs. In Paint.NET v3.36, I had 3 versions of Squish: x86, x86_SSE2, and x64. I knew that going forward this would turn into a rat’s nest of spaghetti code as I added more functionality to the “native” DLLs. Thus, I eliminated x86_SSE2 and switched on SSE “1” for the x86 DLL. There was also some additional native code consolidation. Almost all CPUs nowadays have SSE support, so this didn’t alienate very much of the user base.
- Eventually I will move Paint.NET to require SSE2, for reasons I will discuss later. Requiring SSE is a step in that direction.
Anyway, all this discussion aside, I just discovered that I accidentally compiled Squish to use SSE2. Oops ! The consequence is that if you have a Pentium III or Athlon XP and try to save a DDS file, Paint.NET will just crash, silently close, or print “Error” in the Save Configuration dialog.
You can wait for the next update, Paint.NET v3.5.3, or you can make use of the patch that I’ve published on the forum.
* Actually it has 4, because it also supports AltiVec. However, that’s for PowerPCs, and so doesn’t matter for Paint.NET.
I had a blog post earlier asking why some users had not installed SP3 for XP.
Anyway, the question here is similar: For those users of Windows Vista who haven’t installed SP1 or SP2, why? I receive many crash logs where the user is still on Vista “RTM”, and I can’t think of any reason for someone to be two service packs behind in their updates. For the upcoming v3.5.2, I plan on adding telemetry so that I can get real numbers on this, similar to how I am able to get statistics on OS version, CPU bitness, and locale.
In fact, there are two questions…
- For those who are still on Vista “RTM”, why are you two service packs behind? Why haven’t you installed SP1 or SP2?
- For those are are on Vista SP1, why haven’t you installed SP2?
Part of the reason for asking this question should be obvious: I want to require SP1 (or even SP2!) as a minimum for Vista users (this would not affect XP users). This will reduce my test matrix, and give me more time for other things (like new features, and drinking beer).
In a much older post, I talked about how I did a small experiment with glass. And, just the other day I talked about the latest visual refresh for Paint.NET. Since then, I’ve decided that the free icons available from http://www.pinvoke.com, by Yusuke Kamiyamane, are a much better fit than those from the Oxygen or Crystal sets.
I’m also playing a bit more with glass. Check it out,
Now, of course there are still a few things to work out, such as the left edge of the menu being offset by 1 pixel.
Unfortunately, a JPEG just can’t do it justice (nor could the PNG, even at 5x the file size). It looks much cooler “in real life,” when it’s drawn over your actual desktop.
Paint.NET v3.5 has added support for DirectWrite, a new component in Windows 7. It improves performance, text rendering quality, and reliability when compared to GDI+ or GDI.
DirectWrite is also coming for Windows Vista. Microsoft just released a beta version of the “Platform Update for Windows Vista”, which includes Direct3D 11, Direct2D, and DirectWrite. Check it out here: http://blogs.msdn.com/DirectX/
Paint.NET will automatically use DirectWrite if it is installed on a Windows Vista system. The code for enabling DirectWrite does not limit itself to Windows 7. You don’t even have to wait for the next update, you can do this now! This is all pre-release beta stuff though, so the usual warnings apply. The next update after Paint.NET v3.5 (let’s call it v3.5.1) should automatically install this for you, so that’ll be one less thing to have to remember (computers are good at automating and remembering things, right?).
I’ve been chipping away at the last changes and fixes for Paint.NET before I stamp it as beta and release it to the larger, hungrier “Beta crowd.” This update will be published to users of previous stable versions who’ve opted into public beta updates, and made available via the built-in updater. Hopefully I can finalize and push the stable version out the door to all users by the time Windows 7 hits retail shelves (October 22nd).
Now, the visual styling of an application does not affect its functionality. However, it is a key ingredient for a positive, even enjoyable, user experience. Up through version 2.5, Paint.NET used a 16-color “Windows 95” icon styling. The icons were free, and the style and color palette were very easy to emulate for any custom icons:
For version 2.6, I upgraded the whole application to .NET 2.0, 64-bit, and “Windows XP” / “Visual Studio 2005” icon styling. This was great during Windows XP’s heyday:
For version 3.0, much of the styling remained the same albeit with subtle tweaks throughout. Since version 3.36 was released in August of 2008, to borrow a phrase from Stephen King’s The Dark Tower, “the world has moved on.” It’s quickly looking dated compared to other software and graphics trends.
I decided that I wanted Paint.NET v3.5 to look more at home when installed on Windows 7 and Windows Vista with the Aero theme. To accomplish this, I needed two things: updated visual styling, and updated icons. Visual styling refers to how the menus or highlighted items are drawn, and the first part of this implementation is already in the latest, public alpha release. There are some additional styling changes that will be in the next update, and here’s a preview:
(Note that the close button is simulated in this screenshot, since it only shows up when the mouse is over an image’s thumbnail, which is not the case here. But visually, you should get the idea.)
For non-Aero themes such as Classic or Luna, simpler visual styling will be used. There isn’t enough time right now for further changes, such as glass, but I’ve definitely got it on my radar for version 4.0.
However, icons are much more difficult and time consuming to update. Paint.NET has about 200 of them throughout the application. Some icons are standard and can be used as-is from whatever icon sets I’m pulling from, such as “Open” and “Save”. Others must be formed by combining other icons. “Paste into New Layer” is a good example of this. Others must be created from scratch, such as the selection mode and many effect icons. Some icons are extremely difficult to create; the pan tool (“hand”) and lasso tool icons are easily the trickiest icons ever (yes, I made them both myself!).
Icons are a significant problem for freeware software, both financially and with respect to their creation. While Paint.NET is an image and bitmap editor, I am not an artist. Every once in awhile I can take a good photograph, but that’s an exception and definitely not the rule. Custom icons through a professional studio would several thousand dollars (USD$). Even purchasing several stock icon sets to get a large enough pool of icons to work with would cost around $2,000 USD.
There just aren’t many high quality, free* icon sets out there. For years, I have fed off the freely redistributable icons from Visual Studio and from the very popular and free famfamfam “Silk” icons. Tango is another excellent icon set with wonderful licensing (it’s public domain!), and I’ve used a small number of them for Paint.NET v3.5.
I finally found two icon sets that were free, and whose licensing and distribution requirements were acceptable. They are the Crystal and Oxygen icon sets, which are LGPL and have been popularized via software such as KDE and OpenOffice.org. I don’t use either of those, but the icons are absolutely beautiful and fit in well with the Aero theme in Windows Vista and Windows 7.
With respect to Paint.NET, it’s still a work in progress, but check it out anyway:
Like I said, the authors of these icons released them under the LGPL license. To adhere to their licensing and distribution requirements (they’ve posted guidelines that were very useful), and to avoid converting the entire application to GPL or LGPL**, these icons are not being linked into PaintDotNet.Resources.dll. Instead, they are installed as “loose” PNG files in the Resources/en-US/ directory where Paint.NET is installed. Also, I will be releasing the “source code” for the icon set, which means you’ll be able to download the layered PDN sources for any icon that needed it. For example, the “Open” icon above requires a few layers to achieve contrast, and to separate the folder from the blue arrow. Et cetera. The resources DLL will contain all of the old icons, for reliability reasons. The 2nd exception in the Paint.NET license will be removed. It will also be much easier to customize Paint.NET with your own custom icon sets, although this will not be surfaced as a feature yet – for this release, it is simply a side-effect of the way that the resource manager does resource lookup and fallback.
Thinking ahead, for Paint.NET v4.0 I’m figuring out what direction I want to take the UI. My current thoughts include … glass, ribbonization, how that would work with MDI (or not), extensibility extensibility extensibility, and moving to Windows Vista as the minimum OS requirement. The latter will free me from many of the development constraints I currently have, such as not being able to use Direct2D or many of the shell-related APIs. My experience with dual-targeting GDI and DirectWrite for fonts and typography has taught me that doing something similar with GDI+ and Direct2D would be suicide. I’m only 1 guy, and I simply won’t do that.
Oh, and the tentative, nebulous, waving-my-hands release date target isn’t until 2011. So don’t worry if you’re still on XP: you’ve got plenty of time. And, I think you’ll really enjoy the upgrade to Windows 7***.
* Free in this context means 1) no cost, and 2) compatible license and distribution requirements. Licenses such as GPL are incompatible with Paint.NET.
** Ideological opinions aside, this would not be possible for logistical (legal) reasons.
*** I say this honestly, but also bear in mind that I’m a Microsoft employee so I’m probably biased.
Last Thursday I release a new alpha of Paint.NET v3.5, build 3450. I have rewritten the way that fonts are handled for and by the Text tool. Even if you don’t use the Text tool much, you will still notice some improvements! (see the bulleted list below)
In previous versions of Paint.NET, there are two forms of text rendering supported. The first and the default is called “Smooth”, which utilizes GDI+* to render text. The second is called “Sharp”, and uses GDI. For both, GDI+ is used for font enumeration through the classes in the System.Drawing namespace. Over time, GDI+ has proven to be a poor system for font handling. It has been the cause of many crashes, as GDI+ has a tendency to crash or trample on memory when it encounters fonts that are “bad” (although bad is relative – the font itself may be perfectly fine!). This has led to some people being completely unable to use Paint.NET through no fault of their own.
As a result, I have banished GDI+ from the Text tool. The new builds of Paint.NET are using GDI exclusively for font discovery and text rendering, a change that was substantial in the amount of code that was required and the amount of research that had to be done to make sense of it all. If you’d like to get an appreciation of the depth of the subject, you should check out chapters 14, “Fonts”, and 15, “Text”, of the book, Windows Graphics Programming: Win32 GDI and DirectDraw (Hewlett-Packard Professional Books).
The new typography system in Paint.NET has been designed so that I can plug new text rendering technologies into it. Right now it only supports GDI. For the meantime this means that the choice between “Sharp” and “Smooth” is not available. My next step is to add support for two more text rendering systems, FreeType and DirectWrite (for Windows 7 users**). The former will step in to provide the “Smooth” renderer, and the latter will be added under the name “Enhanced” (or some appropriate name).
In the meantime, you’ll still realize the following benefits in the latest alpha:
- No more “missing” fonts. GDI+ doesn’t support some fonts, notably bitmap, vector, and certain OpenType fonts. I don’t know why. You’ll notice that the new versions of Paint.NET now has a “complete” font list.
- Improved startup performance. It’s ironic that I was telling my manager at work the other day, “Paint.NET v1.0 had poor startup performance – in fact, it was enumerating all the system fonts at system startup, but it no longer does.” Well, because of a bug in my layout code for the toolbar, Paint.NET v3.36 was still doing this! I fixed the bug, and Paint.NET v3.5 now properly defers this to later. I’ve measured the improvement in startup performance at about 15%*** on my systems, and if you have a “lot” of fonts you will no doubt see an even bigger improvement. This is in addition to the already improved startup performance of v3.5 versus v3.36!
- Improved stability. Like I mentioned earlier, GDI+ often crashes when it runs into “bad” fonts (subject to GDI+’s definition of “bad”). Or, it has bugs that lead it to trample on memory it does not own, resulting in crashes which get attributed to the wrong code. GDI does not have this problem. Or, at the very least, if it runs into “bad” fonts, I now control the code that deals with this. I can then make it do something other than crash.
- Installing new fonts. Previously, Paint.NET needed to be restarted for it to recognize any new (or deleted) fonts. I now place a FileSystemWatcher object on the system fonts directory and refresh the toolbar’s font list when changes are detected. There is also a shortcut in the Utilities menu to open the Fonts directory, which will be very useful for helping answer the question that is asked with surprising frequency on the forum: “How do I add fonts?”
* The Wikipedia article states that in the Windows XP timeframe, GDI was deprecated in favor of GDI+. This is not true, although it may have been the altruistic intent at the time.
*** On my personal system, the difference is 0.577 seconds versus 0.405 seconds, as reported by Process Explorer. This is not a formal or exhaustive performance analysis. The precision and accuracy of Process Explorer is not at the millisecond level, hence me rounding all the way down to 15%. The system is an Intel Core i7 920 overclocked to 3.6GHz running Windows 7 RC build 7100. Another system, a Core 2 Quad Q6600 2.4GHz system running Windows 7, reported values of 1.0 second versus about 0.8 seconds, respectively.
Here’s where you can check it out: http://paintdotnet.forumer.com/viewtopic.php?f=46&t=30113
This will not be made available on the website. I don’t even recommend that any download websites host it yet. We’ll wait for the beta for that!
In the meantime, please download, install, and post your comments on the forum.
It’s April and we finally have some sun in Seattle and I haven’t posted in awhile.
Paint.NET runs pretty well with Parallels on my MacBook Pro, although there’s a few quirks to squash. Hmm … they have an affiliate program. I smell a revision to the System Requirements coming soon. Do you know how many requests I get for a Mac version of Paint.NET?
“Should Competent Programms be “Mathematically Inclined”?” — Absolutely, Jeff. I can’t believe anyone would question this. “Math is hard, let’s go shopping!” *faceplant*
Paint.NET v3.5 is coming along, but slowly. I haven’t had as much time or motivation, and it’s difficult when you don’t have a build that works because of ancillary code you broke in areas that you don’t really like (the Recolor tool comes to mind).
Blackjack is fun, especially when you’re winning.
In my previous post, I mentioned that I had rewritten the selection renderer in Paint.NET v3.5. As a pseudo-warning, this post is pretty technical.
The selection renderer in Paint.NET v3.36 uses GDI+. It draws the outline twice: once as a dashed black line, and the second as a dashed white line. A timer fires every 50 milliseconds or so and redraws the outline with a slightly increased “dash offset.” This gives the “dancing ants” animation. Our pal Emma Roberts will demonstrate:
“Pretend I’m animated!” — Ants
There are a few major problems with this implementation. The first is that while you are drawing or modifying a selection, it is only drawn with a black outline (once you are done, it will transition to the “dancing ants” mode). This makes it wickedly difficult to figure out what kind of selection you’re drawing if the underlying area is black. Try it with a solid black image and you’ll understand immediately. I had to do a solid outline instead of a dashed one because there were some horrible artifacts and performance problems if I didn’t.
Next up, the new render cache (hopefully I’ll discuss it in an upcoming post) splits up rendering into more tiles than it did before (for several good reasons!). GDI+ does not do multithreading. At all. In fact, it actively prevents you from making GDI+ calls on more than one thread even if you are clever and “trick” it. This was resulting in selection rendering performance falling off a cliff as all sorts of “setup” work (creating brushes, clipping, etc.) was being over-executed by up to a factor of 10 (that’s an estimate). Not to mention it was a non-starter for multithreaded performance scaling anyway.
Another problem is that the “dancing ants” animation consumes a lot of CPU power. This in turn slows down the rest of the system, and drains battery power (I’m a desktop/workstation guy, but the market has been majority-owned by laptops for awhile now). There are a few optimizations in there to throttle CPU usage if it gets “too high” but it’s never really been profiled or quantitatively proven to work well. My criteria at the time was “fewer people are complaining,” and then I went and drank beer (woohoo!).
Ahem. Anyway. The animation is really there for two reasons: not only does it look cool, but it guarantees contrast between the selection outline and the underlying image. The image you’re working on can’t animate, but the selection outline does, so there you go: it will never be confused for being part of the image.
The solution? I wrote my own polygon rasterizer renderer. From scratch. There’s a good reason people use libraries like GDI+ and Cairo to render graphics for them: it’s tricky! Get someone else to do it for you! Simple implementations aren’t difficult, but the complexity skyrockets once you add things like antialiasing, clipping, blending, various types of caching, serialization (critical for undo/redo), and safe multithreading.
However, I felt it was worth it to implement just enough of a pixel-pushing geometry rasterization “library” in order to render the selection since it is so crucial for Paint.NET. It’s taken “only” 2 months to get right, and it still isn’t quite finished. (but hey, if something is a core business of yours, do it yourself!). I’m now taking polygon lists and doing my own clipping, scanline rasterization, clipping, blending, etc. It’s fun, confusing, educational, and horrifying. I should probably have a cigarette once I’m all done and calmed down.
Bresenham invented the classic aliased line rasterization algorithm, and a kid named Xiaolin Wu later invented a smart antialiased rasterization algorithm. Both are in wide use today because of their inherent and wonderful simplicity. I implemented the latter, because antialiasing is important. The selection outline now uses “XOR” blending, so contrast is guaranteed except for a few less-common scenarios (prevalent 50% grey).
Notice how in this new screenshot, the selection outline effectively changes color as it goes through parts of the image which are varying colors. Where her hair is dark, the selection is bright, and where it crosses her lighter skin tone it becomes darker:
Normally you can’t use both XOR and antialiasing. XOR is meant to be “undoable” and so applying it a 2nd time simply gives you back the original data. It’s generally fast, cheap, and simple. With a naive antialiasing implementation you end up with seams and dots all over your polygon, as endpoints of lines give you pixels that are rendered twice, and very small lines (0 to 2 pixels long) don’t really know what to do.
My solution was to do the rendering in two passes. In the first pass I accumulate coverage values into the alpha channel. I accumulate towards zero, and use the inverse of that later as my real alpha value. I can do this because I know that the pixel is fully opaque at this stage in the rendering pipeline; this is because the “checkerboard” has already been applied. Thus, the alpha channel can be used for whatever I want.
In the second pass I apply the XOR operator to every pixel along the path at full strength (yar!), and then use alpha blending between the original pixel’s color value and the XOR’d color value with respect to the accumulated alpha. Yes, I’m doing stencil buffer accumulation in software. Video games use these a lot, especially for things like shadows and dancing teddy bears (ok maybe not the second one so much).
Oh, also, the selection is no longer animated because contrast is achievable without it, and because the performance benefit is profound. It would also be much more difficult to get an animated or dotted outline with the new code. I’d need 4x the lines of code, or I’d have to employ code generators or some other form of voodoo (if this were C++, a “policy-based template something-or-other” would be employed). As it is I still have a few higher-order functions and closures in there I need to get rid of. But the performance is still great, so I have deferred those optimizations until later (alpha or beta).
Because the selection renderer is now implemented in code that is completely owned by me, all opportunities for optimization are available. This includes changing the underlying storage model that defines the selection’s polygons – I now use a List of Point arrays (List<System.Windows.Point>), which makes interoperating with GPC and WPF easier and faster. I can optimize my clipping and do work ahead of time to ensure that rendering is fast.
I can split work like vector/matrix multiplication across multiple threads. I can even prefetch work ahead of time using “spare” CPU cycles. For instance, whenever the selection changes (moves, rotates, or is edited using add/subtract/union/intersection), I have to recompute the scans of the selection. This is a list of rectangles that I use to fill the interior of the selection with a blue tint. Well, in between the notification of a changed selection, and actually painting it (other stuff happens in the middle), I compute these scans in a background thread. This is a future at work for you!
Also, I can make sure that these “scans” are computed and stored in sorted order with respect to their top Y coordinate. Then, when clipping the rendering of the highlighted selection interior, I can use a nicely fast binary search to figure out which “scan” to start rendering from. Later on I’ll put in logic so that the computation itself can be clipped (I never render the highlight outside of the image bounds, so why calculate that part?). Oh, and did I mention that along the way I found some code on the critical path for the Magic Wand that was using insertion sort? I didn’t? Well, it’s fixed. That was embarrassing.
Other opportunities for optimization include being smarter about which areas of the canvas are redrawn when things change. With GDI+, it was difficult to do the boolean path algebra correctly (because of bugs in GDI+) to find a minimal invalidation region, and so several heuristics were put into place. Now that I control all of the code for both rendering and computational geometry, I’ve been able to implement this better. This improves performance, and fixes some visual glitches whereby little bits and pieces of the selection outline remained when moving/rotating a selection (the heuristic to fix this was, “every 1 second, redraw everything”).
This has all also served to help reacquaint myself with the Paint.NET codebase in areas that haven’t really seen much change in at least 2 years. Therefore, I’m better prepared for more refactoring after v3.5’s release. I’m changing gears for my work on v3.5: I’m going to stop fixing/refactoring things, and move to bugfixing mode. I’ve done a lot of optimizations, and there are still many more possible ones, but I also need to release something so that you all can use it! More optimizations can be trickled out over v3.5.1 or v3.6 releases, etc.
Anyway, that’s all for now. I hope you all will like it. One of my private beta testers sure does:
“…the speed improvements in comparison to my memory of v3.36 are greatly improved on any Windows machine I throw it at. Really well done! I think that this alone will be enough to make people excited.”