We’ve been working on Krita 2.0 since 2006; it looks like we’ll release early 2009, which means it’ll contain three years of work. That’s about as much time as went in to 1.4, 1.5 and 1.6! (If you start counting the work towards 1.4 from when I started hacking krita.)
Of course, it’s impossible to make that comparison, since one thing that took way too much time during 2.0 development was porting to Qt4 and KDE4. Indeed, in retrospect, I feel that we should have waiting until mid 2007 with porting Krita, and spend the intervening time developing a 1.7 version with either new features or a redesigned layer stack or tile system. But we were eager to give the Qt4.0 goodness a try LINKYLINKY — little did we know!
Another reason development is taking so long is that a number of key Krita 1.x features, like the tool system, were moved to the KOffice libraries so all application could use it. In the process, the tool system morphed out of all recognition, and a large chunk of 2006 was taken up with just keeping Krita current and working with the KOffice-wide tool and canvas system — and that work still isn’t completely finished. I think I spent about nine months worth of hacking time on the tools alone — which was an area that was perfectly functional already in 1.x.
A third reason, or maybe it is a consequence, is that the Krita team has shrunk. We’ve been missing the contributions of Adrian, Bart, Casper and Michael. Well, Adrian did most of the initial porting, and Casper has been working on KOffice libraries, but right now, only Cyrille, Sven and me are really active: Emanuele has done great things, but is way too busy with real life for the foreseeable time. Lukas, our 2008 Summer of Code student, is producing some amazing stuff, but he works on plugins, not on Krita itself. There is reason to suppose that the trend can be reversed: Bart Coppens has recently started committing again, which has already made a lot of difference in the latest beta release.
A fourth reason is real life: I got burned out in 2006, mostly from tensions within the wider KOffice project, moved house and changed jobs in 2007, changed jobs again in 2008… That sort of thing does take its toll. Other Krita developers have had real life too, which is only normal over a period of years. As Aaron says, churn is normal, but it needs to be offset by new arrivals. And you don’t get those if you do not release!
But the fifth and most important reason for this long gestation period is that we’ve just simply done a whole lot of work. Krita 1.x already was the only free software paint and image editing application with:
- Adjustment layers
- Layer groups
- Colorspace plugins
- Pluggable brush engines
And for Krita 2, we have developed a host of new features, some of which are unique in the free software world, and some of which are just plain and simple unique. We might have been able to get away with less and release earlier, but we’re peculiarly situated in that we need to release in synch with the KOffice libraries, and those weren’t ready, either.
Let’s try to make an inventory, and determine the state of these features and the likelihood of a complete implementation in 2.0, and the possible development during the 2.x series. And let’s end with noting some regressions from 1.x, features that needed to be removed or disabled to allow development to continue and that haven’t been reimplemented yet.
Note: I’ve added the names of the main authors to the features to give kudos where kudos are due. But we’ve all pitched in in nearly every area of code, so all of Krita really is the work of all its authors. We, if I may say so, rock!
New Features
Pigmentcms Library:
- Who: Cyrille Berger, Boudewijn Rempt
- What: The pigmentcms library is the old Krita color engine moved outside Krita, into the KOffice libraries. In the process it was extended to work not just with lcms-based colorspace plugins, but also OpenCTL colorspace plugins and painterly colorspace plugins. The code was restructured to make it even easier to add new colorspaces. There are some nice, new capabilities, as well. As an experiment, I ported pigment to depend only on Qt, with also the lcms dependency optional, and that took only a few hours. This library really is the goods for anyone wanting to write colorspace independent pixel-mangling code: pigmentcms doesn’t just provide colorspace conversion, but also many operations, from compositing to convolution. Anything that computes with colours, in fact.
- Status: It works really well now and it’s amazingly easy to add new colorspaces and operations.
Floating point colorspaces using OpenGTL:
- Who: Cyrille Berger
- What: As mentioned above, PigmentCMS now can handle colorspaces that do not use LCMS. OpenCTL is a free equivalent of the unfortunately licensed AmpasCTL. It provides primitives to write programs that modify pixels; these programs are then compiled using llvm into native code and executed. Krita uses OpenCTL to provide floating point/channel colorspaces, such as are needed for HDR images. OpenCTL is part of OpenGTL (Graphics Transformation Languages) which also contains OpenShiva (an interpreter for a programming language inspired by Adobe’s PixelBlender, and which apply a kernel transformation, i.e. use multiple pixels as input)
- Status: Works perfectly well. OpenCTL isn’t available as a dependency for every distribution yet because it is still fairly young, but we expect that to to change.
Shader-based filters:
- Who: Boudewijn Rempt, Tom Burdick
- What: Make it possible to write filters using the OpenGL shader language, GLSL. This could, possibly, ensure a nice speedup for some filters, for some colorspaces, and is really cool to play with. The api we designed is similar to Nvidia’s Cg toolkit for Photoshop.
- Status: postponed to 2.1: Tom didn’t really have time enough to finish this, and I don’t have a laptop on which GLSL is working. In fact, my Intel-based thinkpad cannot even handle plain opengl.
Effect masks:
- Who: Boudewijn Rempt
- What: Masks are the combination of a selection and something else: a filter, a transformation, transparency (actually masking out something). They are key to the non-destructive editing capabilities of Krita. This actually necessitated a redesign of our core data structure: the node tree, and for good measure, I did that twice.
- Status: Mostly done. We will certainly have filter masks, transparency masks and local selection masks. Transformation masks won’t make the cut until 2.1 — and even then, they will probably be created by the transform tool, not through a dialog as it is currently implemented.
- Who: Boudewijn Rempt, Emanuele Tamponi
- What: Krita 1.x could embed a single KOffice KPart as an object layer, for instance, a Karbon vector drawing or a KWord text document. This wasn’t very flexible, and one of the reasons for the design of the flake library was to make it possible to share fine-grained object between applications. So Krita now has a layer type that can hold any number of vector objects that are rendered at the document resolution (not the output device resolution) and then blended with the document.
- Status: There are some interaction issues left, but this feature will be in 2.0.
Editable rich text object:
- Who: Thomas Zander, Jan Hambrecht
- What: Not really a Krita feature, but because of the vector layer feature, Krita can now use the flake text shape, which means editable rich text. There is also a simple text shape that can put text on a path; this was created by Jan Hambrecht.
- Status: Definitely in 2.0.
Per-layer metadata editor:
- Who: Cyrille Berger
- What: Since 1.6, there have come into existence new schemes of annotating images, such as xmp and dublin core. We edit metadata per layer, not per image.
- Status: The editor works and supports dublin core and exif, and metadata gets imported from some file formats, but metadata is not loaded and saved in our native file format yet.
Brush engines:
- Who: Boudewijn Rempt, Emanuele Tamponi, Lukas Tvrdy
- What: Krita is the only paint application that has pluggable brush engines. The plugin system for brush engines has been improved: brush engines get more information to play with and can take over the painting of straight lines and bezier curve, as well as painting at a single place. There is a convenience library that contains code for common options, such as response curves to pressure input. And we’ve got some new engines, as well, thanks to Lukas Tvrdy.
- Status: Works, give or take a few bugs. Lukas also added the following engines:
- Sumi-e brush: it started as a simulation of Chinese brush painting, but is now closer to a generic hairy brush simulation. In 2.0.
- Deform: This isn’t in 2.0, but is already done and stable. Paint deformation over your pixels. Way cool!
- Chalk: actually, an early version of Sumi-e — a very acceptable simulation of dry media.
- Curve: Makes random or fractal curves along the line you paint. Ideal for painting coastlines :-). Not in 2.0, although it’s basically done.
- Spatter: old-fashioned spatter-type airbrush simulation. Combined with anti-aliasing and jitter, something very nice. Not in 2.0, but again, it’s perfectly stable.
- Dynadraw: Inspired by Paul Haeberli’s Dynadraw.Lukas is going to do his thesis work at university on Krita brush engines, so we can expect lots more interesting brush engines to appear over the next year. Cyrille Berger has made a programmable brush engine; unfortunatelythat is still in experimental stage.
OpenRaster:
- Who: Cyrille Berger
- What: Interchange file format for layered raster images. Originally started by Boudewijn Rempt to solve the problem that Photoshop’s file format is neither open, nor standard, nor available without an NDA.
- Status: Not too bad. MyPaint is actually the first application to load and save OpenRaster, and Krita can now load MyPaint images. this is big news!.
Guided painting:
- Who: Cyrille Berger
- What: This is a new plugin type for Krita, where the plugins guide, more or less precisely your freehand painting.
- Status: It works, and there is a ruler assistant to test the feature with.
Divine Propertion
- Who: Thomas Zander
- What: Implemented as a flake shape (so usable in all of KOffice), this is a plugin that shows a divine proportion grid on your document. For a future release, we might prefer to implement this as a grid, though — there are already several types of grid in Krita.
- Status: Works, though there are missing icons and the like.
Image resolution:
- Who: Casper Boemann, Boudewijn Rempt
- What: Krita 1.x cared neither about your printer resolution, your screen resolution or the resolution contained in the images you imported. A pixel was a pixel was a pixel. In 2.0, we keep track of resolution and can display the image at the correct size on screen. That means that if you have scanned an image at 300dpi and a 96dpi screen, your image will at 100% zoom be as big physically as on the paper you scanned it from. Get out your rulers and check!
- Status: I’m not sure whether printing actually works — this needs testing by someone who actually has a printer! The rest is done and in 2.0.
Real color mixing:
- Who: Emanuele Tamponi
- What: This started out as Emanuele’s 2007 summer of code project: we wanted a mixer canvas as in Corel Painter, but one where mixing the colors would give real-life results. Emanuele went through many iterations, but in the end came up with a very good approximation of reality.
- Status: The mixing works, there is a mixer canvas and a mixing paintop, but it is not quite done. There are quite a few regressions since the last working version of the code, but I really want to have this in 2.0. The problem right now is that Emanuele is too busy with real life to continue working on it.
Dynamic generators:
- Who: Boudewijn Rempt
- What: The basis for generator layers, a generator is basically a filter that works without input pixels, but only delivers output pixels. This can for instance be used to produce fractals, noise, flames. There is an experimental Shiva-based generator in the Krita2-plugins repository.
- Status: It works, there is a layer type that takes a generator. Not yet implemented, but on the cards for 2.1, is using generators as a fill option in the fill tool or some of the geometric paint tools, as an option instead of foreground color for painting or as a background for paint layers. (Think old paper.)
Clone layers:
- Who: Boudewijn Rempt
- What: A clone layer copies (part of) another layer and inserts it somewhere else in the layer stack. You can then add new effect masks to the copy, for instance to create a blur effect. Clone layers are also important for OpenRaster.
- Status: seems to work, though I’d like some user testing.
Measure tool :
- Who: Sven Langkamp
- What: A tool, not to be confused with the ruler assistant editor tool, that allows you to measure the distance along a straight line between two points.
- Status: Works perfectly, and is in 2.0.
Vector/Pixel selections:
- Who: Sven Langkamp, Boudewijn Rempt
- What: As his 2007 summer of code project, Sven Langkamp investigated ways of improving the Krita selection mechanism. This has resulted in selections that combine vector and bitmap parts. The selections are now shown as marching ants. The vector selection parts are integrated with the KOffice flake system, though not fully. It is not possible to use an arbitrary shape to define a selection, just paths.
- Status: It works, but loading and saving of the vector parts of selections associated with masks and adjustment layers doesn’t work yet.
Color selectors:
- Who: Casper Boemann, Cyrille Berger
- What: Casper first created a color selector that addressed many of the criticisms of our 1.x color selectors: it makes it possible to enter colors in L*a*b and in CMYK. Then Cyrille created a slew of different color selectors, for instance the small color selector that is on by default.
- Status: There is something for every taste. But I don’t think we’ve yet designed the perfect color selector. And none of our color selectors yet shows out-of-gamut color indications. And the big color dialog still is a bit buggy.
Active channel selection:
- Who: Boudewijn Rempt
- What: Applying an operation on just one channel or a subset of the channel of a layer is a powerful capability. See, for instance, this tutorial: . In Krita 2.x, we have made this general. You can select which channels of a layer are active, and only these channels get composited in your image, filters by your filters or painted on.
- Status: Works somewhat: there are still many grave bugs though, and we might have to disable this again for 2.0 final.
Brush engine presets:
- Who: Boudewijn Rempt
- What: We no longer have a simple brush of the potato stamp or abr type as our active brush resource, instead a particular set of settings for a brush engine. The effect of these settings is shown in a preview brush stroke. This is a preset: presets are resources like gradients, patterns or filter presets, so they can be shared, distributed, put into Get Hot New Stuff, loaded, modified and saved.
- Status: Works, give or take a few bugs. Saving changed presets doesn’t work yet, that is planned for 2.1.
OpenGL canvas with on-canvas preview of gradients:
- Who: Adrian Page
- What: If your computer supports OpenGL, you can use the OpenGL canvas. This is faster and uses less memory than the ordinary canvas. If you also have glsl capabilities, your graphics card will be used to preview gradients and also HDR exposure.
- Status: Doesn’t use the selection to constrain the gradient yet.
Improved on-screen zooming:
- Who: Boudewijn Rempt, Casper Boemann, Cyrille Berger
- What: When zooming out, Krita 1.6 would use a very simple and fast algorithm to scale the displayed image. Especially in images with fine detail, that detail would be lost. Krita now uses (when not in OpenGL mode) a much better algorithm, based on one developed by David Dulaney (mosfet).
- Status: Works pretty well, gives very good results. There are some display glitches sometimes, but it is not certain that it is caused just by this feature, and there isn’t much performance degradation, although there is some. The next step would be to use an image pyramid approach, which is something still on Bart Coppens’ TODO.
Action recording:
- Who: Cyrille Berger
- What: By switching on the big brother system — the action recorder — you will get a script that contains all the actions you used. You can later replay this script, either as a kind of simple script, or as a demonstration of some technique. Scripts are simple XML and can easily be shared.
- Status: Works pretty well, although editing of recorded actions isn’t implemented yet, and not everything is already integrated with the recorder. And I broke recording of the active brush selection, but that should be fixed for 2.0.
On-canvas preview of filters:
- Who: Boudewijn Rempt
- What: Given that we have filter masks now, it was an easy decision to try to use a temporary mask to give previews of filter settings right on the canvas, instead of in a scaled-down preview image.
- Status: Works, though there are some performance issues.
New tile backend:
- Who: Bart Coppens
- What: Krita’s tile backend dates back to Patrick Julien. Casper Boemann made it possible to have auto-extending layers (as in Photoshop, but as opposed to Gimp). However, in a multi-threading age, the current tile backend is hampered by something called the The Great Big Krita Lock. Additionally, there are other infelicities. Bart Coppens set out to remedy that by creating a new tile backend.
- Status: It’s not completely done, and not really performance tuned yet. Besides, some code in Krita, notably in the filters, makes incorrect assumptions that the new tile backend show up. Unfortunately, that results in crashes. The new tile backend won’t be enabled in 2.0.
Compresed tiles:
- Who: Boudewijn Rempt
- What: Compress old tiles (undo information, for instance) in memory, and write them compressed to the swapfile. This would save us quite a bit of memory, might help with cache hits and would certainly help in the performance of the swap file.
- Status: Sort-of worked, but wasn’t stable enough to enable by default and has now fallen by the wayside. Still on the cards for 2.1, though, since it might save us a lot of memory.
Multi-threading of many operations:
- Who: Boudewijn Rempt, Cyrille Berger
- What: Many operations, such as filters, that work on either a large area of a layer or on many layers are prime candidates to be multi-threaded so we can make use of multi-core processors. We implemented this in several ways, mostly making use of Threadweaver: there is a KisThreadedApplicator class that takes a layer, a job and an area and autodivides the area in chunks and creates jobs. Painting is threaded: that means that we queue your strokes and handle them in a background thread. Many operations that span several layers are threaded, such as scaling or color transformation. That’s why Krita now has a progress bar for every layer and mask in the layer box.
- Status: Like a curate’s egg, parts of it are excellent. At one point recomposition was handled in threads in the background, but some algorithmic problems made us revert that; I am working on a new approach. And, actually, I should check whether scaling images is multithreaded right now.
There are also several new plugins, for instance for tonemapping, bracketing to hdr, panorama stitching, compose (the converse of separate channels), with more in the Krita2 plugins repository.
And finally, there are two big new features: Krita runs on OSX and on Windows. Getting it installed is still a bit hard, but they run:
Regressions
Bird’s Eyeview docker: the zoom and pan widget in the overview docker. Because we’ve got a shared canvas and document architecture now, this can be implemented KOffice-wide. Martin Pfeiffer (the winner of the KOffice GUI design competition) intended to implement this, but he has disappeared, as far as we can tell.
CImg filter: I knocked up this filter as a quick experiment in the 1.x days, but I never managed to actually maintain it. It’s not colorspace independent, very slow and gave a lot of horrible compiler warnings. We recently moved it to Krita-plugins. Some other filters didn’t get ported either: colorify and halftone.
Vector tools: Emanuele Tamponi implemented path drawing tools and path selection tools — including a wickedly cool magnetic selection tool — during the 2006 Summer of Code. Because we share vector tools with the rest of KOffice now, these vector tools were never ported. We do have vector selections and vector painting with Krita brushes now, but not the magnetic selection tool.
Selection masks: Sven Langkamp created a marching ants selection and a mixed vector/pixel-based selection operation for Krita during his 2007 summer of code project — however, in the process showing a selection or a mask as a mask got lost. This also has to do with our repainting reimplementation.
Threaded recomposition: Well, this was never in 1.x, but I had it working for some time during the 2.0 development. I had to disable it when I redesigned the recomposition strategy, but it’s still on my todo for 2.1.
Brush outline cursors: with the new painting engine of Qt, the XOR operator is no longer supported, which makes it rather harder to have a brush outline cursor. This is still a todo.
Watercolors: our pride and joy: we removed this colorspace because of the problems with undo it gave, and designed a new architecture to make this more generic, as part of Emanuele’s Summer of Code Project. But wetness never made it into 2.0, although the color mixing we have now is much better than in the old watercolors colorspace.
And, of course, there are still some TODO’s from the 1.x days, like a history docker.
Plans that were completely dropped
Canvas rotation and overextending: We really want it to be possible to rotate the canvas to match the rotation of your tablet, and to show the contents of layers that have been moved beyond the boundaries of the image. The first is really hard to implement now that we are using a KOffice-wide canvas object (which is necessary to make the tools work), the second is something I had working,LINKYLINKY? but which, after refactoring of the KOffice library code, was no longer possible.
Conclusion
Excluding pigment and the other KOffice libraries, Krita is now about 120,000 lines of code. About half of that is plugins; the other half is split between 30.000 lines of core code and 20.000 lines of code for the user interface. That is actually not much more than for Krita 1.6!
Our core code is in a much better shape: we’ve got an extensive set of unittests, we have better separation of concerns, a better design for many data structures. We’re down to only a few hundred Krazy issues. There are still plenty of bugs, though, that really need squashing. And the user interface code hasn’t kept pace: looking at Krita 2.0 and 1.6, the 1.6 interface is much easier to look at, less cluttered in any case. That is something to keep working on: but then, that’s the idea of free software: something to keep working on!