Paint.NET 4.0 “fine grained history” and other stuff

One nice thing about the Move tools in Paint.NET is that they implement something I call fine-grained history. When you go to edit a selection or move its pixels around, you get 1 history entry for each adjustment you make. This allows you to move it around, rotate it, etc. and then when you press “Undo” it only backs out of the most recent adjustment you made. Contrast this to the Gradient, Line/Curve, and Text tools which don’t keep track of each edit you make and can only undo things wholesale.

Recently I’ve been working on adding this to the Gradient tool for 4.0. This support will then make its way into the shape tools, and probably the Text tool as well (also, shapes will be undergoing an overhaul soon). The reason I’ve been working on the Gradient tool is that it is a fairly simple tool and this allows me to get the code for fine-grained history working without having to worry about as many “moving parts.”

Here’s a screenshot showing the Gradient tool having gone through it’s initial “draw” operation, followed by two “edit” operations:

(click for full resolution version)

Once this makes its way to the new Shapes tool (not yet written unfortunately), you’ll be able to: 1) draw a shape, 2) move, rotate, resize the shape, 3) change the colors, 4) change the stroke, 5) change any other properties, and then 6) finish/commit it to the layer. Currently the shape tools in v3.5 are fairly barbaric and don’t even let you change their color or other properties once you’ve pressed down the mouse button. It can be quite painful if you are consistently off by a few pixels and have to constantly redo your Rectangle until it’s just right.

There are some other important benefits to doing this. I’ll be able to significantly reduce memory usage, for starters. In Paint.NET v3.5, the tools are implemented in a rather cumbersome way. While you draw, it’s modifying the layer data so it contains what you’re drawing … then it draws that to the screen. Then, when you move the mouse it has to copy back the original contents of the layer before drawing the new stuff. When you’re done, it has to copy back the original pixels, save it to disk, then redraw everything one last time. This is implemented with a very carefully debugged protocol that requires all sorts of data to be copied around various buffers before, during, and after any edit operation. Any bug in the protocol for drawing, copying, and emitting history entries can lead to data loss.

With the new system, the gradient (et. al.) draws itself using a layer overlay, which only affects the rendering pipeline and not the image itself. Undoing the edit before it’s committed is a simple matter of throwing away the overlay. When it’s time to commit the drawing, the code just says “hey I changed this rectangular area” and then a simple diffing algorithm copies away only the parts of the layer that changed. There’s no need for me to manage complicated geometry masks and dirty regions any more (other than what’s needed for an active selection, of course). All the large and temporary (and permanent, ack!) buffers are simply no longer needed.

This is all very important! Reducing memory usage is very important for an application like Paint.NET, especially on 32-bit systems. This also removes another barrier toward migrating to a fully tile-based memory allocator, which then opens up doors for many other very, very cool features.

Another benefit to doing this is that it moves the tool rendering code off of the UI thread and into the rendering pipeline (which was already moved off the UI thread for 4.0). The UI will always be responsive while you’re drawing, even if the canvas is still “catching up” to what you’ve done. It’s pretty cool to be able to throw around the Gradient tool’s “handles” (aka “nubs”) and see them responding at a much higher framerate than the canvas itself. If you’ve ever had to work with an image that is very large, or has a lot of layers, or both, then you probably already know that this will be a great thing.

Also, right now the Move Selected Pixels tool is a monster (for me that is; not for you). While it does work perfectly well, the code is wildly complicated and fragile. Adding or changing any features would be a recipe for disaster. By migrating it to this much simpler system, I’ll be able to reduce memory usage further, increase performance and quality, and remove any “hitch” you may notice at the start of a move operation. The reason the “hitch” happens is that the history data (the layer’s pixels) must be saved off into a temporary buffer before any rendering can be done. Afterward, there’s a frightening dance of copying pixel data from the layer to a scratch area, and then transforming pixels from a 2nd copy back to the layer, and then undoing it all before redoing it, etc. The nightmare gets worse when history entries come into the mix. The code is basically the worst time travel paradox you could possibly imagine – I can’t honestly say I fully understand how it works, even though I wrote it. What I can say is that it works, but only because it’s been thoroughly and exhaustively tested, debugged, and bugfixed.

Oh, and you’ll notice in this screenshot that I’ve finished up the last bits of UI reorganizing. I’ve done away with the Window and Utilities menus. Instead, each of the floating windows has its own toggle button at the top-right. The gear icon opens up the Settings dialog, and the question mark icon gives you the traditional help menu. Anything that was in the Utilities menu has either been moved into the Settings dialog, or removed. I‘ve also increased the size of these icons to 24×24 because I found they were just too darn small at 16×16.

Within the Settings dialog I’ve added a Diagnostics page which gives you a peek at your system information as Paint.NET sees it (basically the information that’s printed at the top of a crash log, and more). It will also give you access to the crash logs folder and some other simple things that should make troubleshooting a bit simpler. Oh, and for those who don’t like the “dancing ants” (animated selection outline), I’ve included a checkbox to control whether this is on or off (not on the Diagnostics tab though).

In time, I hope to elaborate further on what I mean by “this stuff opening doors for other very cool features.” I’ve been throwing around ideas for the last few days and it’s exciting how much things are radically simplified by all this. I’m hoping that 4.0 will serve as a solid basis for many, many features over its lifetime. 4.0 won’t have all the features everyone wants, but it will enable me to finally add so many more of them!


36 thoughts on “Paint.NET 4.0 “fine grained history” and other stuff

  1. John Christian Lønningdal says:

    Nice update on Paint 4.0! I have a wish/suggestion for your next version though. Is there any way of having the floating windows docked? Whenever I use I find myself moving the floating windows a lot as they are frequently “in the way” of where I am working. I think they would easily fit to the right or left if you do some relayout of the Colors window. Since most users today have a wide format monitor, they wont steal much of the workspace for a typical photo format either and allow a user to see the whole picture even with the tools docked.

  2. Uwe says:

    Will there ever be the feature of dockable toolbars so that my canvas is accessible even in the highest zoom order and in every border, without forcing me to drag the toolbars every now and then?

    I think even Gimp plans such a feature.

    • Sidneys1 says:

      Personally I think a better solution than dockable toolbars is just allowing us to pan past the edge of the canvas.. Maybe not all the way, but at least so the edge is in center screen.

  3. Kurt (@kurtextrem) says:

    Looks great! 😀
    But one suggestion:
    Implement Folders for Layers

    And one question:
    Is there any SVN / Git Repo for the code? Or a downloadable .exe from pdn 4 alpha? I wanna try it out 😀

  4. Tom says:

    I really like the way palette visibility is handled.

    That looks like a handwritten message in the third open file. Is full tablet support back? I remember pressure-sensitivity was disabled in Paint.NET to workaround a bug in .NET 3.5 (or maybe it was SP1).

  5. Peter says:

    In this way the image thumbnails (on the top and in the layers window) are not updated until you submit the gradient (press enter).

    • Rick Brewster says:

      This is true, and a particular astute observation. But, I’m really not too worried about it. Also, if I really wanted to, I could make sure that the image and layer previews do include the overlay. I’m just not convinced it’s necessary, or desirable.

    • Rick Brewster says:

      I believe I’ve gone over this before in another blog post and/or its comments. I’ve evaluated the ribbon, and deemed it wasn’t a very good fit for Paint.NET. The ribbon is fine on its own merits, but in particular it does not work for MDI applications (which isn’t my only reason).

      • Johannes says:

        Thanks for the answer! I wasn’t sure if I read something about it on here before.
        Good lock with the drive towards 4.0!

  6. John Quigley III says:

    The UI for Paint.Net looks like it is coming along rather well, but the icons for utilities and help are rather pixelated even at their small size.

    • Rick Brewster says:

      The Settings icon (the gear) does need a little smoothing out, and is something I’m planning to do eventually (it’s not really a high priority right now). The Help icon looks fine to me.

      • John Quigley III says:

        Okay that good to know, I really love the work you have done so far with Paint.Net. I use it for my Fallout 3 and New Vegas Mod work and I have made my sprite comic in it as well.

  7. botpride says:

    Hello Rick,
    just a couple of ideas how to extend working space (for image editors its really important):
    – poke main menu into the non-client area button (like in Opera, Firefox, and so on). Since DWM variant is much easier than hand-made frame for XP, probably it would be OK to limit such variant of menu only for Vista/W7
    – whenever possible, join two toolbar bands in one row (at your picture, there’s lot of unused space to the right)
    – make an option to hide statusbar (sb is useful, but quite seldom)
    – add a full-screen mode, where major toolbars will appear if mouse strikes screen sides (something like panels in FastStone image viewer)

    And one more idea: I’ve noticed, that big plugin packs are loaded very long, freezing PDN at start. May be it would be a good thing to load them in async way (showing somewhere status that not all plugins are added yet). Furthermore: it would be nice to have a stats for plugins usage and load them in such priority (most used effects appearing in menu first!)

    What are your thoughts?

  8. Martin J. Pollard says:

    Loving Paint.NET; I have Photoshop Elements 10, but Paint.NET lets me do 99% of everything I need to do without PSE’s learning curve. Kudos!

    I do have a suggestion for 4.0, and apologies if this has already been made or is already planned. Whenever I start the app, I have to always reset the settings for the various tools to the way I want them. (Example: I prefer to keep the Color Picker set to “switch to previous tool.”) Can you add the ability for tool settings to be “sticky,” so that you don’t need to set them to your preferred configuration every time you start the program? Heck, you could even make the “sticky” ability an option, for people who don’t want their previous settings to stick.

    Okay, I have two suggestions. 🙂 Somewhat related to the above, the ability to export and import the program’s settings would be nice, too. That way, we could easily set Paint.NET to our preferred configuration on multiple machines (i.e. desktop and laptop), as well as quickly configure the program in case we need to reinstall it (such as when moving to a new computer or a reformat-and-reinstall).

    Thanks again for such a great program!

      • Martin J. Pollard says:

        Okay, I’m an idiot. 😦 Thanks for pointing that out. Now, if you’ll excuse me, I’m going to go flog myself with a wet spaghetti noodle for my total n00bness. 🙂

        • Rick Brewster says:

          In 4.0 these settings have been moved into a more appropriate and much more discoverable location … *drumroll please* … the Settings dialog.

          • Martin J. Pollard says:

            Sounds like a winning plan to me! Add the ability to import/export settings and you’ll be batting a thousand. 😀

  9. Triscal says:

    It looks really great I am so excited to get 4 in my hands when it comes out. I agree with revamped utility windows/toolbars.I also think it would be amazing if there was folders/drop down menus for history. so if I need to fine to a gradient for a while then decide that I don’t want it at all I don’t have to undo tons or scroll up. just undo the folder. If i wanted to just undo my last edit I could open the folder then start undoing there.

    But looks amazing!

  10. VitalyT says:

    Are you ever going to offer at least Beta version of Paint.NET 4.0? Your roadmap seems to go pass the release of .NET 4.5 early next year.

  11. Mark Biernat says:

    I am looking forward to 4.0. I have been using for a while, I have tried other photo editors but always find my way back to because of the simplicity and speed coupled with the ability to do professional photo editing.

    The gradient improvements as well as the brush improvements are something I look forward to.

    I am an amateur, so I dare not make specific requests to drive the direction of this development as I might misdirect things.

    However, maybe if someone wants to create a plugin for ‘retro vintage effects’ that are one step and click this could be useful.

    Another idea, although it might not be realistic for a photo editor (as opposed to DTP) would be a print quality PDF export plugin.

    I recommend to people over anything else because it continues to evolve and is easier to use than anything else with top of the line power.

  12. Johnny Westlake (@JohnnyWestlake) says:

    Looks like work is going well 😛 Although, I’m not entirely convinced with placement on these new buttons – they seem like they’re taking up more space then is neccessary… which might not be great for those with lower resolution screens. Even for those without though they still take up a lot of room – though to be fair it’s nothing that’s going to stop me or anyone else using it. I’d suggest putting them in the status bar but it looks like that’s being put to good use already.

    Although more importantly – as much as I appreciate you needing and deserving to make money via adverts on the site for your great work on Paint.NET, I can’t help but think of the amount of users who have accidentall ended up installing crapware thanks to the ads – they’re downloading buttons are far more prominant and in your face – even I got confused at one point – it’s a little crazy – they’re not even clear they’re downloads for other products – See this shot!

  13. Robert Grant says:

    Is there any plan to allow text layers a la Photoshop? I know that PS must be a tiresome comparison for you, and I know the standard “it’s a raster editor, deal with it” answer, but it is such a crucial feature for designers. Will 4.0 allow anything like this?

    Thanks, I’ve been a Paint.NET evangelist for years, it’s a great, great bit of software.


    • Rick Brewster says:

      I get asked this about every 5 minutes. Someday. Probably not in 4.0, but hopefully in 4.x. It requires that layer masks be implemented first, otherwise there’s no good way to clip the text. Once you see layers masks, text layers are “unlocked” as a possibility.

      • Robert Grant says:

        You got asked it again because I couldn’t work out how to vote up feature requests on the Paint.NET site 🙂 Thanks for the reply, glad to hear it might be on the way.

  14. Tyler says:

    On several occasions I’ve been zoomed in to about 800% on a small image while making a texture for a videogame, but when I need to draw near the edge of the canvas, things get difficult. It would be great if you allowed the ability to scroll slightly off the canvas (similar to what Sydneys1 said several posts upward).

    Another feature I’ve thought of recently is edge wrapping, or the behavoir of the left edge of an image being directly attached to its right side. This would be great for making tiled textures, but there are probably not enough users that would use it to justify implementing it…

    Anyway, thanks for

Comments are closed.