Past

First Krita sprint that I attended was back in 2010, in Netherlands, Deventer. We were hosted by Krita maintainer, Boudewijn Rempt. The main topic back then was to define product vision for Krita . It was a great idea to invite Peter Sikking. He helped us define very cool vision for Krita. If you have a vision, you can decide easily what to include into your application, what to implement and what can be provided by external applications. It helps you to decide whether you have to agree with user complaining in bug report or not.

Next Krita sprint was in 2011. The location was very cool: Blender Instituite, Netherlands, Amsterdam. For me the most important moment from that sprint was when artists (Timothee, David Revoy,…) demonstrated how they use Krita. It helped us to identify the biggest problems, focus us on polishing parts of Krita that were causing problems for professional painters. We managed to fix those issues since then, Krita has changed a lot since then, it is used by professionals these days!

Timothee painted me in his painting session on the roof

We failed to organize Krita sprint 2012 in Bilbao, Boud and me were too busy. We probably did not plan Krita sprint 2013 for the very same reason.

Present

Krita sprint 2014 was held in Netherlands, Deventer again. We were hosted by Boud and Irina and it was as great as back in 2010. I arrived on Friday, 16th of May. After travelling for a little bit more than 11 hours using public transport, I managed to arrive to Deventer safely. Train, tram, bus, airplane and train and there I was! When I plan such a journey, I tend to add time paddings to have enough time for travel connections, so that’s why it takes so long. My traveling agony was healed by Wi-Fi almost everywhere!

The main discussion was on Saturday and it is nicely described in DOT KDE article. I personally was wondering how Krita Foundation is doing. So far Krita Foundation is not able to employ all Krita hackers full-time, but I hope one day it will be possible!

One of the steps towards that goal is Krita Kickstarter: it will allow our community developers Dmitry and Sven to work on Krita full-time for a longer time period. I hope it will be a huge success and maybe next fund-raiser will allow more community developers (e.g. me ) to work on Krita full-time again. Well, it is more complicated for me now when I have my own family, my wife and a little son to care about.

There are full-time developers who work on Krita projects commercially in KO Gmbh: Boud, who is the maintainer of Krita and few employees, who entered Krita development through KO Gmbh: Stuart, Leinir and Arjen. First two were also present at the sprint! Their work is mostly on Krita Sketch, Krita Gemini and Krita on Steam and this commercial work is feeding them. All their work on Krita is open-source development!

We had nice lunch outside together on Saturday. Then we had hacking time til dinner and after dinner. I was working on G’MIC integration into Krita. This time I was fixing problems with internet filter definition updates. Then I spent some time with Dmitry discussing problems I faced when integrating G’mic into Krita. There are some use-cases that our processing framework, responsible for multi-threaded processing of the layers in Krita, is not counting on: I suppose that it is because we did not have enough focus on image filters. Krita is painting application and filters are usually needed for photo-manipulation. But painters also need to post-process their paintings, so that’s why I’m working on G’mic integration.

Sunday was dedicated to artists: Steven, Timothee and Wolthera showing us how they use Krita, what they struggle with and what can be better. Observing artists using Krita allowed us to see where Krita is right now. In 2011 it was not yet suitable for professional painting, in 2014 we could see that Krita made it into professional league of painting applications.

We spent some time just hanging around and discussing stuff around Krita. We had nice walk to the park, spent time on the roof of our hosting place or walked in the town. It was great to meet old friends and meet some new faces.

We also got some presents from Krita Foundation, nice t-shirts for everybody, one t-shirt was made specially for my little son — thank you! I brought something for Irina and Boud: some Slovak cheese products and slovak wine — oštiepok was especially enjoyed by Boud and Irina.

Big thank you goes to Boudewijn and Irina for excellent hosting and to KDE e.V. for making the sprint possible.

Field of painting that Krita explicitly supports is also creating textures for rendering. This field gets attention mostly these days. Transform tool was improved just recently.

One bug, that caught my attention, was about transforming layers with offset. It is essential image pixel transformation if you want to produce seamless textures.

I started to work on it before our Calligra Essen Sprint 2013, then there I made some progress together with dmitryK. Dmitry next to me made the integration much more faster as Dmitry knows processing framework used in Krita very well. Now I clean up rough edges and I’m trying to support corner use-cases like multi-layer document with transparency masks and other crazy possibilities that are available in Krita. As you will see in the video, texture artist is usually using one layer in most cases.

Anyway, the offset transformation can be found in Image menu and Layer menu. If you have multi-layer image and you want to offset all the layers, you use Image->Offset. If you want to offset only active layer, you go to Layer->Offset menu. The default coordinates in UI point to the center of canvas or if you have active selection, to the center of the selection.

mifth, Krita user and graphics artist, that reported the bug, was so kind, that he prepared video demonstrating the feature

To support the texture workflow even better in Krita, it would be nice to implement texture analysis and synthesis filter. For GIMP there is plug-in called ResynthesizerGiven a sample of a texture, it can create more of that texture. Auto-magically!

Greetings from Essen! The 2nd day of Calligra sprint in Essen started with discussion about redesigning UI in Calligra so that the applications can be delivered easily on more platforms. The first candidate for UI code refactoring is going to be Krita. There is already Krita Sketch application which provides QML based user interface besides the standard QWidget one. Rest of the Calligra suite should follow the refactorings too.

Maintainers are needed! Karbon, Plan and Braindump are without maintainers. Previous maintainers are busy with real life.

Afternoon was full of commits and coding. I made code review for Krita Sketch merge to master and then Boud, Krita maintainer, started to fix the problems I found. Sven is working on actions and operations, so that users can produce macros. And he did some refactoring, so now you can write less code to produce extensions with actions. Dmitry was trying to compile Windows version of Krita, but that failed. He helped me also to implement offset operation for layers and image, especially part related to processing framework in Krita — if you have image with 8 layers and your computer has 4 cores, every core will process one layer, so you get the filtering results quickly! Dmitry also fixed some crash in transform tool. Arjen worked on modern OpenGL canvas for Krita.

Friedrich was fixing build system in Calligra, he introduced so-called Productsets, so now you can easily specify that you want to compile Calligra for Plasma Active with only useful parts and avoid compilation of the parts that are useful only for desktop version.

Yue is fixing some text layout bug. Matus Uzak fixed some problems in filters and worked on docx export filter. Inge started to lay foundations for export filter for docx. He has experience with epub that is constructed from odf and also experience with export of odf to html. Thorsten fixed bug with styles in filters related to footers and headers, that were not saved correctly. He also reported some bug for me, what reminded me of my time when I was working on Calligra for Nokia and I investigated shortly some bug in MS Office filter.

Today I was riding a small electric car provided by Linux hotel. It is called Renault Twizy. I was picking up pizzas for lunch. It was funny to ride in Essen-Horst, I enjoyed it a lot. The car does not have windows (now I see the pun from linuxhotel), it is quite small and elegant for city travelling! The speed change is so smooth in this electric car. Then we had nice dinner in a restaurant — some had tasty Schnitzels and some tasty vegetarian food.

Calligra sprint 2013 is taking place in Essen, Germany. We are occupying Linuxhotel, which happens to be a very nice Linux hotel. The rooms are nice, the meeting hall is nice. Cool place with Linux mascot everywhere. I like the equipment of the hotel. Coffee machine, kitchen ready to be used, rooms with computers, even an acoustic guitar.

The first day started with a lot of discussions. Some are personal, some are technical.Sven, Dmitry and I were discussing recording, macros and actions in Krita. Inge and Matus were discussing docx export filter. Hopefully it will happen!

Arijen and Thorsten cooked really great dinner for us. Pasta with tasty sauces, one was vegetarian and tasted great even for me, non-vegetarian person. The other one was with meat. Nobody stayed hungry. Mek, Sheets Tables maintainer, happens to work for Google now and he brought Google Chromebook Pixel.I can confirm that the display is really amazing on this device. Boud shared some positive impressions from Mobile World Congress about demoing Krita.

Few remarkable quotes of the day:

“Krita is actually useful product, that people can use.”

“You are married…You are Lord of the Rings now.”
“Yeah, the ring makes me invisible in the commit log.”

I spent 5 days in Vienna, participating at the Libre Graphics Meeting 2012. It is conference full of developers, artists and users connected to open-source tools. You can meet there MyPaint, Gimp, Inkscape or Scribus developers. At least I did! Or you can meet some independent developers who created cool custom open-source tools and very nice people interested in design.

Besides the regular program we visited Metalab. It’s part of the Hackerspace scene. It is a great place for hackers to meet and build stuff. Not just code, but also hardware, photography or food. Metalab is full of interesting geeky stuff like laser cutter, 3D printer or game consoles since the age of Atari! Pity that something like that is not close enough to me. I had very nice conversions with LGM friends there. Let’s review the conference from my point of view. But first I would like to thank KDE for sponsoring me the travel expenses!

TL;DR: Very interesting stuff everywhere.

First day of the conference was full of color management talks. Richard Hughes talked about ColorHug and colord. ColorHug is interesting piece of open source hardware: display colorimeter. It allows you to calibrate your screen for accurate color matching. More information on the official website.

Kai-Uwe Behrmann talked about OpenICC and Oyranos. Chris Lilley about color management in SVG2. I don’t understand this topics, but I read very good article about it recently, so if you are confused about it, go ahead and read it. It is important topic, if you print photos or you want to calibrate two monitors to show the colors in the same visual way.

Second half of the day started with lovely Russian Valek Filippov. He was talking about re-lab project which is about reverse engineering of the proprietary formats for the compatibility reasons. I used oletoy from this project back then when I was working on Calligra. For investigating Excel files it was really great and helped me a lot! Valek’s presentation was followed by Fridrich Strba (who comes from Slovakia by the way, go Slovakia! :-]), he talked about LibreOffice and support of the proprietary graphics formats in LO.

Igor Novikov presented the restart of the sK1 Project. Next presentation by Behdad Esfahbod was very interesting, he was talking about rendering of the text on the GPU. With this approach you can free CPU from performance CPU-consuming tasks like rasterization. It’s way to go on low-performance devices like smart phones.

Ramon Miranda is involved in Gimp, MyPaint and Krita as the artist and the creator of brush presets. He is famous for his GIMP Paint Studio. His presentation was important for me as he was talking about painting and that is always interesting to me. His background lays in traditional art and he is exploring digital painting. And he is exploring it very successfully producing nice art. Very talented painter and nice man. Martin Renold (Maxy), original creator, developer, maintainer gave talk about “Predictive painting” in MyPaint. I could not miss it. I always like to talk with Martin about painting algorithms.

Tom Lechner talked about lovely tool, his Laidout contains many fancy tools not available in other packages. I liked that you could put pictures on curve for example. HarfBuzz, the free text shaping engine by Behdad Esfahbod catched my attention too.

From the “An awesome FLOSS design collaboration work-flow” by Máirín Duffy and Emily Dirsh, Sparkleshare caught my attention. It’s a git-backed, dropbox-like system that automatically checks in and pushes files to a shared git repository.

On Friday I started with Powerstroke in Inkscape. Very nice effects were demoed. You need Inkscape trunk for Powerstroke to be able to play with it. We might take some inspiration either for Karbon or maybe even for some vector brush engine for Krita.

Then train of GIMP related talks started. Peter Sikking, interaction design guru, and Kate Price talked about text handling in GIMP. OpenCL in Gegl and GIMP by Victor Oliveira: Mesa is implementing OpenCL support! NVidia, AMD and Intel provide proprietary solutions so far. Øyvind Kolås a.k.a. pippin with some Gimp developer mitch talked about Gegl integration in GIMP. Recently a huge step was made towards integrating this very fast, important back-end (e.g. 16 bit per channel) for pixel buffers. Many pictures with goats were presented.

Tube Open Movie by Bassam Kurdali was actually remote presentation. Bassam sent video to organizers and it was projected for the whole audience. Then he answered some questions through #lgm IRC channel.

Peter Sikking, me and Timothee shortly before the Krita talk

Saturday started with our presentation about Krita. Together with Timothee Giet, a.k.a. Animtim, we presented some new workflow improvements in Krita. Curve brush, multi-hand and mirror painting caught some attention too. Tom Lechner had nice suggestion for multi-hand tool: Escher-like strokes. Then we showed some piece of art done by Krita. Timothee Giet then continued with his talk about animation with Synfig studio.

Then I attended Krita workshop about workflow to create illustrations and comics with Krita where Timothee showed Krita in the real-world usecase. It was very well attended workshop, around 22 people there, full room of people. We found some problems with Krita 2.4 in Fedora package. Now I realize that it was probably disabled feature shortly before release and already available in master (full-screen canvas with ‘Tab’ key). I use Fedora, but I never use the packages, because you can’t have installed both. Krita 2.3 is by the way very old. Please refrain from using it. Krita 2.3 misses so many work and features, many of those that Timothee presented in his workflow. You can get Krita 2.4 for Fedora 16 in testing KDE repo. Few problems found at the workshop: old 2.3 version, disabled feature in 2.4 and brush editor is too big for netbooks

Closing talk by Louis Desjardins. It was decided that the next LGM is going to be in Madrid, Spain. Handshakes with familiar faces, visiting Vienna and travel back home. It was great time to be there.

The event was covered by blogposts and ideas from talks were picked on twitter/identi.ca. Here are few I found:

5th november 2011 since the early morning til the late night (almost) no matter where you are, the Krita IRC channel #krita on freenode.

This bug hunting event is about help you to try Krita, it’s about finding hidden bugs in your Krita workflow, it’s about getting to know more people from community. We will help you
build lastest Krita if you want or you can come and test prepared packages for your Linux distribution (Krita 2.4 beta 3).

There are few Krita developers sponsored to work on Krita part-time and I’m one of them. It’s all donated by one man from Krita community, Silvio Grosso. Big thanks goes to him. Thanks to this initiative I can spend few hours a week on ugly Krita bugs. Besides that I’m still contributing to Krita as a hobby developer. Mostly by new features 😉 I blog after I finish milestone of 50 sponsored hours so here I go.

Some peaceful picture for a little too technical blog post

I started with bug 250978. It says, that stylus X/Y Tilt sensors are broken. Tilt comes from your (Wacom) tablet. I found out that the sensors were not broken, but tilt support, that artists except, is not about directly taking the values of tilt X and tilt Y from Qt event and use those, but you have to compute one value based on these tilts. The inspiration came from befriended project mypaint. The solution was to implement new sensors, namely declination and ascension. It is nicely described at mypaint wiki. Fixed and the outcome was happy artist.

Next bug was about the performance. Experimental paintop was kinda slooow and flickering. I had some discussions with Dmitry Kazakov, Krita developer, as he had some nice idea, but the idea is not general enough, but still might be worth to try to implement it, but later. Basically it is about the way we construct the shape of the experimental paintop. But it does not take into account the dynamic opacity of the whole shape or deformation of the shape. Flickering was fixed by trick similar to double buffering. I was rendering the shape directly into layer and then remove it fastly every brush dab. And the update algorithm of Krita flickered in that case. So now I render and remove the shape on the paintop’s internal device and it does not flicker anymore. I also improved the performance of the paintop by doing tricks when converting Qt’s QPainter polygon into Krita’s colorspace aware pixel buffers. David Revoy says he is happy with the speed of it, compared to Alchemy. I’m not happy yet as I have slower hardware as David, but I don’t have any idea how to improve it for now.

Then I investigated and worked on some smaller bugs. We had problems with our presets. We save XML into PNG file into metadata part. Because we save doubles (like 1.246) as strings, they were sometimes saved accourding the system locale. So in some countries like 1,246 and in some like 1.246. Then we load them with QString::toDouble(bool * ok) and we did not checked the ok value. Who does that? Have you ever checked printf() return code? We should checked it. We discovered the problem when Krita artist from Argentina send the presets to share them. I was not able to load them in English locale system. Some important preset values were zeros. So we fixed the loading with Sven by using mighty german locale when loading old presets if we fail. 1.246 and 1,246 are loaded ok in german locale. Now we save the presets without honoring the user’s locale settings. There might be some problems still present.

Then I investigated some slowness with paintops, but it lead to the pooler and that is maintained by Dmitry so I handed the bug to him. He successfully fixed it.

Rest of the time I spend with speedsensor bugs. I still did not nailed it. Basically I try to adopt mypaint solution with low-pass filtering on the speed computation. Maxy from mypaint was very helpful. Speed is computed now in the tool (was in the sensor itself) and will be computed even when you hover the canvas. The result is still not smooth speed, so I have to debug the code.

That’s it. Current plan is still bug fixing and making Krita more stable, faster and polished! I will continue in this work in my pace and I look forward to inform you after the next milestone!

There is an open drawing project, called Alchemy. I noticed this project while watching some video tutorials made by David Revoy. He uses this tool in his workflow. I noticed that people can draw crazy interesting stuff with that tool. I wanted to have those features in Krita for our users. I also wanted to kill Alchemy in David’s workflow (evil laugh) so that he can use Krita more in his workflow.

Here is the vision of the Alchemy project, just for the reference and before I kill the Alchemy userbase with Krita (exaggeration of course):

Alchemy is an open drawing project aimed at exploring how we can sketch, draw, and create on computers in new ways. Alchemy isn’t software for creating finished artwork, but rather a sketching environment that focuses on the absolute initial stage of the creation process. Experimental in nature, Alchemy lets you brainstorm visually to explore an expanded range of ideas and possibilities in a serendipitous way.

Now is the time to mention our shiny Krita vision:

Krita is a KDE program for sketching and painting, offering an end–to–end solution for creating digital painting files from scratch by masters. Fields of painting that Krita explicitly supports are concept art, creation of comics and textures for rendering. Modelled on existing real-world painting materials and workflows, Krita supports creative working by getting out of the way and with snappy response.

David Revoy’s workflow contains mainly shape and mirroring mode from the Alchemy. So I started and focused on those features and I tried to implement their adaption for Krita. There are other features in Alchemy, that are nice to have, but my spare time is limited so I prioritize!

Shape feature

Let me share some developer details. First let’s talk about the shape feature. Basically it allows you to paint the freehand form shape. Every new mouse move adds triangle to the shape, but some triangles make the shape non-convex and that means that the shape is transparent in the place where the triangle bisect the shape.

Piece of abstract art demonstrating
non-convex freehand shape

Alchemy is vector graphics application, Krita is raster graphics. First problem was how to render the shape correctly with raster brush. I wanted to create some new brush engine — it is possible to realize this feature like this, e.g. Pinta can do this shape with its tools. But, but..brushes just leave the trace, how do you want to render the shape, which is changing under your hand like some kind of animation as you stroke? I did not shared yet that the shape can be pre-processed and post-processed which imply that it can change from dab to dab. The opacity of the shape can be dynamic too, it can be like random, controlled by pressure. Dmitry, Krita folk, had nice idea to use mean of the pressure, because when you activate the opacity contoller with pressure, you will not see the shape, because the sensor pressure sends low value when you raise your pen from the tablet.

Made with shape and mirroring
By me and my pc mouse

The solution I come up with is to first render the part of the stroke, next time erase the previous part of the stroke and render the whole stroke (previous and new) again on the unchanged background. We call some part of the stroke dab.That way the opacity can be dynamic, shape can change as it will be re-rendered everytime from the beginning.

Implementation details (feel free to skip): The rasterization is done by QPainterPath and QPainter and the result is used as alpha mask for our various color-spaces. Thank you, Qt. First attempt was using data that we store to our pixel buffers for undo action, we name it oldRawData(). Also pixel filters use those data sometimes. Before the stroke begins, you have the original unchanged data of the layer there until the end of the stroke – those are there because of the Krita’s transaction system. The whole stroke is one transaction for every brush engine. This attempt somehow worked, but it was slow. I pinged Dmitry, our transaction, tile engine and multithreaded developer and he advised me to make copy of the current layer and use those data to erase rendering of the previous dab. I used some tricky commands that activated the tile sharing of the pixel buffers and auto-magically it was much more faster. The only problem that left was some flickering. Also the speed was still not perfect, but closer to “snappy response” (see Krita vision). Next advice from Dmitry was to use transaction directly. Cyrille Berger advised this in the beginning, but somehow I did not know how to realize that idea and Dmitry showed me some pseudo code with those transactions. Lesson learned: ask for the pseudo-code. I implemented the advice. All the rendering was done on the layer directly. That caused that flickering of the canvas. So I had to do some kind of double buffering. Now all rendering is done on the internal device which is the copy of the layer and the flickering is gone. Speed is almost ok, there is no more flickering.

Mirroring

Another interesting and funny feature is mirroring of the stroke. You paint on the left half of the canvas and the stroke is rendered also on the right half and it is mirrored. Crazy fun.

You want to paint two mirrored Batmen?
Yes, you can…with Krita!

I implemented this feature first for the brush engine that has features from Alchemy (the shape feature described above) as it is needed for David workflow. I realized soon that this can be generalized and done in our freehand tool, that means for every brush engine, that we have. Yes, now we have two buttons in the tool bar for vertical and horizontal mirroring. This mirroring is implemented as dab mirroring. When you smudge the pixels in your canvas or if you deform them with our brush engines, the pixels beneath your cursor are used. The result of the brush is mirrored and placed in the correct mirrored position., but the smudge or deform is not done on the image. It has it’s purpose too. It’s fast, and it’s fun also.

Red icons turn on the mirror feature (Krita 2.4 alpha)

Some of our artists usually use git master, so that they have the candies like mirroring faster, so I’m glad that I can share already some art produced with mirroring feature:

Some tests done by David Revoy in Krita with mirror feature:

Multihand tool

Ok, but I want to mirror the behaviour, I want to smudge or deform both sides! maybe you say, dear Krita user. You want to smudge both sides of the image and mirrored. For that I created a new tool for you dawg. Tool, that does not mirror the result, but mirrors the stroke of the freehand tool. But about that in some future blogpost.

My full-time sponsored developing of Krita ended few months ago and I’m already working in my day job as software developer. So far it’s fun, I enjoy my new work place and colleges and basically I’m happy to work in the environment with people — that’s what I was missing about when working from home alone.

Silvio, the great Krita sponsor, is the man who decided to put Krita to the next level by sponsoring me and Dmitry working on Krita part-time. Big thanks to Silvio! I promised to blog about the progress, so here I go a little bit late as being busy with new work and life. I think part-time version worked fine so far. I managed to deliver 51 hours of work.

I started to fix the brush mask generators. I fixed few rendering bugs, usually some artifacts and I fixed little inconsistency with them. If you setup spikes to rectangle mask and change the ratio, you supposed to see the spikes in the mask. At least that is the behavior in GIMP and in Krita we did not computed the spikes for the rectangle brushes. Fixed. When I worked on this bug, I noticed that the quality of the brush mask in the curve mode is quite bad, especially when you rotate the mask. Oversampling helped. The curve mask works in that way that it samples the curve created by user. When you do oversampling, you take more samples from the curve. When the user wants circle with radius 10, I used to take 10 samples. Now with oversampling, I take 4x more, so 40 samples. I did some tests with it and 4x seems to be the right number of oversampling. Also GIMP uses this multiplier.

Using spikes in rectangle mask generator
Let’s spray some stars

Then I worked on the brush outline bug. I added new option to the Pixel brush called density which can be used to simulate chalk effect. Problem with density is that it creates complicated brush outlines. In Krita the brush outline is constructed from QPolygons inside QPainterPath. Pixel-sized holes causes, that the outline is constructed from a lot of small QPolygons. So far the fix is that when there is density used, the outline does not show the holes. This problem is quite big, if somebody creates brush with a huge amount of pixel-size holes, the outline will be rendered slow. Some more proper solution will be needed.

Then I decided to support Dmitry, who is also sponsored Krita developer, working part-time. He had a lot of bugs assigned before release and my code paths were quite release ready. So I investigated bugs with filters. I discovered that some filters in Krita are actually direct ports from GIMP and that means that they ignore colorspaces and work wrongly if you have e.g. RGB colorspace with 16-bit per channel or more. I managed to fix only blur filter with Cyrille Berger’s help and mentoring. We disabled other broken filters for the release.I did some bug triagging too.

Then I fixed some unit-tests which has to pass before the release. I fixed the autobrush unit test, that is crucial for Pixel Brush in Auto brush mode. And then I fixed benchmarks as they were crashing.I also fixed jpeg unit test, it failed with some version of JPEG library. Then I spent some time investigating the shape layer bug with scaling, but too much new code area to me. Sven managed to fixed it much more faster then me. I was also doing some icon work, I fixed bug with the select similar color icon.

That’s it. Next report after I deliver at least 50 hours Thanks to the Krita developers and community for the support!

Besides my sponsored work on Krita, I work in my spare time (if I find some) on some new features. I did a thesis about brush painting and I still enjoy this topic. So when I find some new interesting brush, that might be usable, I’m trying to adopt it in Krita as a new brush engine. Few months ago I discovered project Harmony and I liked the brushes there. Especially Sketchy, Shaded, Chrome, Fur and Long Fur. The idea for those brushes comes from concept of connecting neighbour points. The concept was realized first in Scribbler and Harmony was inspired. Then I adopted the Harmony version in Krita.

The adoption has some advantages like undo/redo and some different and new features and one drawback.

New features compared to Harmony

Highly configurable

You can create new brushes, because I adopted all five brushes from Harmony as one big brush engine with parameters. I explored the code and came up with names for the parameters, which influence the stroke of the brush. So you can change the size of brush easily. In original Harmony project, the area is just circle with fixed size, that detects the points. In Krita it can be any brush tip (ellipse, flower, chain). I don’t how much is this usable, but at least I found ellipse quite useful compared to circle. Anyway you can create more effects compared to the Harmony version.

For performance reasons you will find in Brush size dialog checkbox called Simple mode, which means that again circle area will be used if check. For the size of the circle, the size of the brush tip you choose in Brush tip is used. What is the performance problem here? Maybe you need some big circle and rasterization of that circle as brush mask is quite slow. On the other hand checking the points in this simple mode in the circle is quite fast no matter of the size.

The main options for the brush are in Brush size option dialog. Let me describe them a little. Line width is new feature compared to Harmony. You can setup the width of the line that is used as connection between the points of the stroke.

Sketch can stroke with different width of the connection lines

Offset scale is partially reverse engineered from Harmony. It influence the size of the connection line between two points. Actually it changes the offset of the start and end point of the connection line. Here I need to work on better UI, because now it is confusing. When you setup the offset to 0% or 100%, it looks same. Weird, right? You can see the demonstration on of it on the next picture.

Offset scale: 60%, 90%, 100%, 200%

Density influence the number of lines. When the brush detects point in the neighbour, it starts to think: Should I make a connection? Hm..let’s look at the density.Ah, density is 100%, why I’m thinking about, of course make a connection. When the density is e.g. 20% the brush think like this: Hm…density is 20%, that means 1 line from 5 detections of neighbour points should be rasterized. Let’s roll the dice. Oh, I can’t make connection – neeeext! There is also related checkbox option called Use distance density. This one uses the distance of the points and dice to decide if to make the connection. It changes the size of the brush due to the way it computes the density of the lines. If you setup 50% density, check the distance density and use the brush tip of size 64, it will usually make connection only for points that are in the distance of 32 pixels and will also roll a dice if it should make a connection. This option is from original Harmony project. I wanted to control the density just by dice, but I wanted to make presets that mimics the Harmony and I needed this one.

Density 100%, 20%, 1%

Magnetify option decides whether to connect the current point with points from stroke or to make line with offset right and left and the current mouse position. If the brush is not magnetifying, the effect creates nice fur effect. Tweak the offset scale to get nice effects.

Fur effect in Sketch

Random opacity checked causes that in every line has random opacity. This effect was present in Harmony.Random RGB checked causes that the color of the single line is distorted per channel by random generator. This was needed to support Chrome from HarmonyDistance density checked causes that the connection line will have density according the distance between points that are going to be connected.Paint connection line checked paints connection line between two positions of the brush always (previous mouse position and current mouse position).

Then I added support for tablet to the Sketch. I implemented it through standard Krita dialogs like Size sensor, Opacity sensor and Rotation sensor. So you can use also different sensors to change the size like fade or for rotation drawing angle. Size sensor changes the size of the area where the detection occurs. Opacity sensor changes the opacity of the dab. In one dab there can be many lines rendered as many points are checked — it is not per line opacity, that’s why there is Random opacity. Rotation sensorrotate the brush tip shape, which is used for detecting the neighbour points. I usually use the ellipse and setup the Rotation sensor to drawing angle. Thanks to the lately added dynamic outlines you can see where it is detecting the points.

UI feedback

You can see the size of the brush on canvas. In Harmony you see just the cursor. I have to improve the situation – somehow the center of the brush is also important. You can switch to showing the cursor instead of the brush outline to temporary workaround it but I plan to add some cross in the middle of the shape.

Undo/Redo

You can’t undo the stroke in Harmony, you can in Krita 😉

Missing feature compared to Harmony

The detection between the neighbour points occurs only per stroke in Krita’s adoption. In Harmony you can connect to points from previous strokes. I put this problem on the feature list for 2.4 as that is not support in our API yet – to be able to store information about previous strokes somewhere. Brush engine life span takes from the start of the stroke to the end of the stroke. You don’t have information about previous stroke available in the brush engine. Slovak (me) and Russian (Dmitry Medvedev Kazakov) Krita developers will take care of this feature together as it needs to work correctly with undo/redo. Question is if we also want to connect to points only on the same layer or per layer or make it optional. We will find out something.

Future

This brush engine is in experimental state and will be released in Krita 2.3. Experimental brush engine means that the presets you make might not work in Krita 2.4 as the UI will be changed (improved of course) and the brush engine is still under development. I hope to add the missing feature for 2.4 and polish the UI.

Finally

There are presets that mimics the Harmony brushes: Sketchy, Shaded, Chrome and Fur (I lost the Long Fur preset, but I will try to fix it). They are installed with Krita, so you can explore them and tweak them as you wish. Preset is the setting of the brush engine saved on the disk if you did not know. The Ribbon brush from Harmony is already in Krita, behaves little differently and it is called Particle brush in Krita. Other brush engines are for me less usable and quite specific so, I do not plan to port them (yet).

Thanksgoes to the author of Harmony, Mr. Doob for co-operation. He wrote about Harmony on his blog. Check the Flickr, Google where you find images that can be done with Sketch brush in Krita.

If you create (please, do..) something nice, please, sent it to our gallery at Krita forum.