James Richard Tyrer speaks out:

“Someone posted that TQM had to be forced on people. Possibly, but the question is whether after it is forced on them that they ever want to go back to working without it?”

I’ve been a professional software developer for more than ten years now, and I’ve been through all the fads, all the processes, all the acronyms. The only ‘process’ that ever gave me any pleasure was extreme programming, and even then only the pair programming with a congenial colleague part. Yes, having experienced the kind of top-down, heavy-handed programmer-shackling that TQM and the other acronyms stand for, I say: never again.

The problem, James, with TQM is not the Q, it is the M (and the T a bit, because Total reeks of totaliarism). If I am donating my time and my work as a volunteer to an open source project, I’ll be damned before I’ll allow myself to be managed. Especially by someone who hasn’t earned my respect at all. And there’s no way, short of taking away my CVS account, you can force me to comply.

If someone whose work I admire tells me to fix this, do that, or pull up my socks and start producing better code, I’ll probably heed him or her. But that’s the only kind of management I’ll accept.

Suggestions, snide remarks about lack of commitment, snipes and other pointy-haired behavior won’t influence me in the least. Which translates to: if you want to have real influence, James, learn C++, and learn it well. Impress me. With something more substantial than flaunting an acm.org email address.

A dashed little comma

Can spoil four evenings. Now I know that I am not at peak form when working in the fumes of paint, and we have had painters in the house for three days (they did a beautiful job, and I heartily recommend them: Steenbruggen in Deventer) — but, dash it, see if you can spot the mistake in this Makefile.am:

INCLUDES  = -I$(srcdir)/../ $(KOFFICE_INCLUDES)  -I$(interfacedir) $(KOPAINTER_INCLUDES) $(all_includes)

noinst_LTLIBRARIES = libkiscapabilitymediator.la
libkiscapabilitymediator_la_LIBADD = ./paintops/libkispaintops.la
libkiscapabilitymediator_la_SOURCES = kis_capability_mediator.cc kis_abstract_capability.cc, kis_composite_op.cc kis_paint_op.cc

libkiscapabilitymediator_la_METASOURCES = AUTO

SUBDIRS = paintops

Seen it? I only spotted it tonight. You’d get really weird errors in the linking stage of the main Krita lib, but linking the core lib just worked…

On the other hand, things are hotting up a bit. Patrick Julien is busy as ever with his day (and night) job, but two more people have come on board, and there’s another friendly soul who likes helping me out with performance issues. So — there’s life again in the five year old dog!

What — am I a hacker, or what?

There’s this heading ‘hacking’ on Fading Memories, isn’t it? Hacking, and not coding. But what’s a hacker — when it comes down to it? It’s, perhaps, someone who’s been sharing code against all odds for longer than he cares to remember, someone who has a sense of esthetic regarding code, even more than regarding ephemera like user interfaces. Perhaps a hacker is a coder who’s just that little bit harder to herd.

So — what am I — I mean, am I, or not? Not exceptionally bright, like Paul Graham, but I’ve been coding since 1982, been using Linux since 1993, been learning a new programming language every — on average — three years. I think I know by now; I’m a hacker, and I dislike being herded.

Not that there’s much chance of that: whenever people show up and try to convince coding people that Process is Paramount (note nice reference to Quick Service) and TQM is king (or is that Queen?), I smile enigmatically (not that that is much use in an on-line discussion) and refrain in a refined way from commenting that those attempts are futile and vainglorious. There’s no way someone who cannot code for toffee can get me — let alone people who can code really well — to do his bidding. I’ll follow my own agenda, thank you very much. If you like it, fine, tickled to death, I’m sure, if not, learn C++ yourself, it’s not that difficult, my dear man.

So, if I’m a hacker — what’s my forte. Not audacity of design. Not actual knowledge — when working on Krita more than half the time I do not know what I’m doing. I have little math and less computer science. But a kind of dogged going on coding, because I want to see what it does and learn what makes it tick. That’s my ticket. Sometimes a programmer’s gotta do what he gotta do.

A while — quite a while, actually — ago, there was a bit on O’Reilly Network that tangentially discussed the set of features that makes a hacker a hacker. In the cause of full disclosure and unmitigated boasting I must add that I: hate Heinlein (silly racist right-wing loony), like Tolkien, like van Gulik better, play the clarinet, fence, despise gun-bunnies, wish I had the
necessary moral righteousness to conform more closely to the ideals of the FSF, still play RPG’s, know zilch about RPGi-the-language, know (a bit or quite well, it depends) various basics, PL-SQL, SQL, C++, Pascal, Java, C++, Python, SGML, XML and, scraping the barrel a bit, SNOBOL. I paint a bit, have written a novel, a book, a number of articles, am a linguist — but all that is mere outer trappings.

The most important thing is, I think, that whenever I see something that’s cool, that seems to work, I want to know why, and how, and more importantly, how can I make things like that, or even better. Preferably better. That whatever I do seldom is better isn’t the point. It’s the attempt that counts — in a Newt Pulsifer kind of way. That, and being unherdable, of course.

Which neatly brings me back, and from there to another rant: Why do so many people who take a certain philosophy lock stock and barrel think they’re the ones who think, while the poor shmucks who have chosen something else must be incapable of cogitation?

People who think they have achieved a freedom of thought because they’ve bought into the free-thinkers thing seem to me pretty naive — given to take a label for its contents, for one thing.

Give me one of the great Gregories (Nyssa, Nazianze, the Great) any day above those shallow ‘thinkers’ who cannot get beyond ‘Either one believes, and does not think, or one thinks, and does not believe’ (Bert Keizer in Trouw, this week).

Just like Frederic Brooks, I think, therefore I believe

Some progress, at least

Progress with Krita has been slow, the past two weeks, considering that I’ve been at home nearly permanently. Still, I’ve been working on some things, and thinking about others.

There’s now an eraser tool, and a line tool, and I made a start porting the stamp tool. At least, I thought that it was a stamp tool, but it turns out it is a tool that paints with patterns instead of brushes, not something that takes the last selected bit of the image, and paints with that. Perhaps I’d better wait for Patrick Julien to checkin the odds and ends for selecting and pasting he says he has lying about, and make a start on a convolve tool.

I also ported (that’s to say, copy, paste, search & replace) a large number of less interesting composition operations to Krita from GraphicsMagick, after I was given the green light by Leonard Rosenthol about the licensing. The more interesting composition operations are harder to port, since they either work on a whole image at a time, instead of on regions, or they use a number of extra functions from GraphicsMagick that I don’t feel the urge to port, too.

A persistent pain in the neck with working on Krita (or C++, perhaps, I am not sure), is the hard-coded nature of everything. With Python I can define a number of classes, perhaps even dynamically, read a list of classnames in a Python list from a configuration file, iterate over the list and instantiate the classes — easy as pie. But that’s because in Python, classes are an object; in C++ classes are — I don’t know what, exactly, but not objects, and no fun either. Look at Python:

class A: pass 
class B: pass
class C: pass
class D: pass

l = []

for clsname in file("classes.cfg").read().split():
print l

Of course, this is a very simple-minded example, but image a situation where you have a large number of classes, say — for the sake of argument — composition operators, one class per op, and you have a smaller number of image types, and some comp. ops. are useful for all image types, others only for a few, and others again for only one. The GUI, of course, must show only the relevant composition ops in the various listboxes. And when I add one, I don’t want to have to go through all the code to add those.

But still, I’m prepared to do precisely that: hardcode the instances of the relevant ops in the correct places, Krita, however, currently doesn’t have anything like that. There is a long enumeration in kis_global.h; there are user-visible string somewhere else, and a big switch statement that uses the enum to switch between function calls.

Here, I should create a factory that creates all defined ops, and some kind of a database that ties together all functionality, preferably defined in a configuration file, but hardcoding will do for now. I’m not sure about naming; I need something that forms the basis of all these capabilities that are now described in enums, and inherit from there.

Likewise, KisPainter is big monolith that looks a lot like QPainter. It combines geometric functions with simple paint functions, but that’s unpleasant, because I would prefer to have one function for creating lines that I can feed not only brush types and things, but also paint operations: hard paint, soft paint, airbrush, convolve, erase — so, instead of:

void eraseCircle(Qpoint p1, Q_INT32 radius);
void eraseLine(QPoint p1, QPoint p2);
void eraseAt(QPoint p);

void eraseLine(Qpoint p1, Q_INT32 radius);
void paintLine(QPoint p1, QPoint p2):
void paintAt(QPoint p)

void convolveCircle(...

I’d like:

class PaintOp;
class erase;
class convolve;
class paint;

class KisPainter{
void line(const PaintOp & op, QPoint p1, QPoint p2);
void circle(const PaintOp & op, QPoint p1, Q{Point p2);

Etcetera… Add in a CompositeOp class hierarchy, and life will almost seem to be as sweet as Python makes possible again. Of course, there’s more… We already have a KisResource structure that handles brushes, patterns and other bits of artistic licentiousness that are read from disk; here we have a lot of code duplication, even though the process is fairly dynamic.

And I should finish that convolve tool.

No hacking…

Hacking is just as much a necessity of life as breathing, writing or eating. But sometimes, it’s impossible to go on working, even though you’re all in the flow.

Like when Johanna decides that she’ll punish you for putting a row of books on her favourite sleeping spot; she won’t move to the other side of the desk, but in front of kis_strategy_colorspace_rgb.cc

The books have been put back to the left side of the desk, where I prefer to push my monitor so I have some deskspace for reading, but well, one  cannot have everything, and it is nice, having a sleeping ball of black, cuddly fur on your desk while working.

(And the other reason for not working on Krita is that the fever has dropped off a bit, and I’m just too tired right now, so excuse no new commits, I’m  just goofing off and looking through my stack of photos…Here’s a piccy of another cat, Hendrik, reading Dostoievsky, which I think is pretty nice.)

Why Free Software, and why hacking even when quite ill?

This article by an anonymous person tells you why — near the bottom: And now a word from our corporate sponsors

Let the stuffed shirts and corporate bigwigs make money from the Free code. Let the pundits question what it will take for Linux to succeed on the Desktop. There is massive innovation in Linux userspace, driven by the same geeky joy that, in another era and in other fields is called “intellectual curiosity.” That’s what I see as the main force behind the Open Source movement; not corporate possibilities, as the LinuxWorld convention pretends, but brutal candor, mischievous smartness, self-mocking over-eagerness. The corporate successes of Linux are just the results of an overflow of energy, the excesses being mopped up. The hacker ethic is driving the corporations. We don’t need them, but they need us.

Intellectual curiosity it is — that, and the intense desire to make things, to, in fact, create. Before I kept a blog, I already found it necessary to write about that — Apologia, because people kept mailing me, asking why the thingy I found it necessary to spend time on creative pursuits, like conlanging or world building.

And now I’m not only working on a novel, on a language database application, on a KDE paint application, but also studying theology and messing with real paint again.

Worrying about composition

Gah! I never had proper maths at school, and I dare say that if someone had tried to teach me maths at the tender age of eleven or twelve, I’d probably have bucked like race horse that’s harnessed in front of a brewery sledge. But the fact that my maths teacher walked out of the class when I was in the second form, to never return, didn’t help either. Not that I ever thought I had missed something essential.

Until now, that is. Graphics == maths, it seems. And not simple algebra eiher. So I am trying to understand what the various composition modes do — reading the literature, starting with the Porter-Duff article that appears to have started it all, and working my way through the GraphicsMagick source code, and I am finding it hard going.

And then there’s the mess that Krita’s UI is, a rich archeological dig where you can find code from 1999 to 2003, all written by different people with different goals and different styles, and practically nothing finished, or even in a working state. I should scrap that GUI and start again, only that’s going to take even more time from that most elusive of goals: a working eraser too.

Anyway, here’s a snippet of GraphicsMagick code, for the ‘in’ composition operation:

	if (source.opacity == TransparentOpacity)
	if (destination.opacity == TransparentOpacity)
	pixel.opacity=(double) (((double) MaxRGB-source.opacity)*

	destination.red=(Quantum) (((double) MaxRGB-source.opacity)*

	destination.green=(Quantum) (((double) MaxRGB-source.opacity)*

	destination.blue=(Quantum) (((double) MaxRGB-source.opacity)*
	destination.opacity=(Quantum) (MaxRGB-pixel.opacity+0.5);

And here’s how I think it should be translated into Krita:

d = dst;
s = src;


	memcpy(d, s, stride * sizeof(QUANTUM));


alpha = (double) (((double) QUANTUM_MAX - s[PIXEL_ALPHA]) * (QUANTUM_MAX - d[PIXEL_ALPHA]) / QUANTUM_MAX);
d[PIXEL_ALPHA] = (QUANTUM) (QUANTUM_MAX - alpha + 0.5);

dst += dststride;
src += srcstride;

But it doesn’t seem to work:

I am not completely sure what ‘in’ ought to do, but I am fairly certain that it isn’t ‘paint vertical black lines’ if I’ve selected a purple brush…

That dashed TODO list keeps growing

I’ve spent the better part of this week rather feverishly (literally, I’m afraid) hacking on Krita, trying to bring it up to KPaint-level feature-wise, at least, and all that seems to happen is that my TODO list is growing.

Yesterday I fixed that silly slider that regulates the spacing with which brushes are painted on the canvas, did some code clean-ups and made sure the correct cursors are used. And I updated that TODO list:

* The tabs for images inside a document seem to be broken :-(
* Brush cursor shapes for tools (updating cursors from the tools doesn't work yet).
* Give each layer its own imagetype; allow layers of diverse types in one image.
* Option dialog for tools
* Make tools kparts
* Fix scrollbars
* make brush tool antialiased; make un-antialiased pen tool
* If you have a tablet, you can have more than one active tool at a time: 
	stylus, eraser, pointer and your ordinary mouse, not to mention
	the possibility of having several styluses.
* Implement saving/loading of tool properties.
* redo configuration dialog
* Find a way to set the hourglass cursor when doing complex things from
	e.g. KisPainter.
* Make pipe brushes pay attention to the instructions in the 'parasite'
* Use patterns and gradients while painting


And that’s just the bit that got added this week. And I would really like to bring some more structure in the /core source directory, and make a  separate library of the KisPaintDevice/KisPainter code. But that’s a refactoring that can be done at a later stage, when I’m more confident of my C++ abilities. I am growing more confident — I think I could put C++ on my curriculum vitae by now.

The thing that’s most needed at the moment is more tools; that will flesh out the KisPainter interface and give me a reason to improve the user interface. Having more than one layer type in one image would be a good thing, too. That would make it easy to have a CMYK or B/W layer and a layer with spot colour on top.

Gimp’s pipe brushes

The Gimp nowadays comes with a small set of rather nifty brushes — the so-called pipe brushes, recognizable from the file-extension .gih. The fileformat for these brushes is actually really horrible, a mix between text and binary. The first line contains the brush name, the second the number of brushes the brush contains, a space, and a bit of text detailing the way the brush ought to be used.

Today (and yesterday) I spent time creating a class that could load those brushes, and actually use them. Well, that’s done. I still don’t parse the bit of text — a ‘parasite’ in Gimp parlance — so you just get all the images in the brush in order, and I don’t make a difference between brushes that are really gray-scale masks to be used with the currently selected colour, and the brushes that are really collections of images that can be pasted into the drawing directly.

But on the other hand, I support pressure-sensitivity for every pipe brush:

Pity that pre-computing all those masks takes such a lot of memory. Krita now wants about 256 MB of memory at startup…

Gosh, Python is easy

I’d almost forgotten how easy Python is, how comfortable it is not to have to recompile, how nice it is not to have to type all kinds of superfluous punctuation… Java is better than C++ in this regard, but still… Compared to Python.

Interest in Kura is picking up a bit, and I am getting bug reports and feature requests. And that forces me to go back to this source. Source that I started writing in august 1999, that has been through a rewrite (from PyKDE-based to pure PyQt), that I haven’t looked at for months. After all, it did what I wanted it to do, it was sufficient for my current needs, which is keeping track of language data for the novel I should be working on.

And I can still find my way around the code, make a change, no need for five minutes of compiling, restart the application (it loads on Debian/PPC in under a second, OS X is far slower), and check whether the fix worked… (Dash it, there is something wrong with my webcvs.cgi script…

Pity you cannot do an optimized natural media paint application in Python. In fact, I sometimes find C++ enough of a paint that I wish I could do Krita in Java, using gcj…