Footprint algorithms: in the stamp, or in the paintop?

Emanuele Tamponi emanuele at valinor.it
Tue Mar 25 19:10:58 CET 2008


Il Tuesday 25 March 2008 11:30:05 Cyrille Berger ha scritto:
> That said, the priority for Krita 2.0 would be KisStampManipulator (with a
> better name), all the rest can happen when we have, at last, make that
> release.

Well. This has a flaw, and I hope to very clear at explaining it.
If we use KisStampManipulator, we are still relying on a certain paintop 
to "build up" the behavior of the stamp.

Let me explain...
Imagine: we will prepare a set of KisStampManipulator classes, each of them 
transforms the input stamp in something different, taking pressure, tilt, et 
cetera into account, at paintop discretion. We can imagine something like a 
chain of manipulators that the paintop can build up to obtain the final 
stamp.

This way, the code that "builds up" the stamp is in a particular paintop: for 
example in KisBrushOp there will be the chain that builds a brush-like stamp.

But what happens then? It happens that a particular chain is binded to a 
particular paintop. You want a brush stamp? You've to use KisBrushOp! You 
need a pencil stamp? You've to use KisPencilOp (or KisPenOp).
But again, these paintops not only decide how the *stamp* will look like 
(size, shape, position, et cetera); they decide what to do with that stamp 
too (and, as everyone knows, they just "print" the stamp onto the canvas 
using the current color).
So, with this infrastructure, KisPaintOp does *two* things:
1) Takes a certain stamp from KisStamp and applies to this stamp a chain of 
manipulations.
2) Decides what to do with this manipulated stamp.

I think that these two operations needs to be separated. A certain class - 
indipendently from KisPaintOp - has to take and manipulate the stamp using 
current information and settings. Then the paintop has just to decide what to 
do with this ready-to-use stamp.

To make the difference more evident, consider this simil-code:

1) This is how the code will look like with Cyrille's suggested structure:

KisBrushOp::paintAt(information)
{
    stamp = currentStamp(information);
    manipulatedStamp = applyBrushManipulationChain(information);
    
    stampDevice->setColor(currentColor);
    bitBlt(stampDevice to canvasDevice);
}

KisPenOp::paintAt(information)
{
    stampDevice = currentStamp(information);
    manipulatedStamp = applyPenManipulationChain(information);
    
    stampDevice->setColor(currentColor);
    bitBlt(stampDevice to canvasDevice);
}

KisCloneOp::paintAt(information)
{
    stampDevice = currentStamp(information);
    manipulatedStamp = ?????????? <---- You see, here, what will the
                                  manipulated stamp? A Brush stamp?
                                  a pencil stamp? And what will happen
                                  when the number of different chains
                                  will grow?
    
    bitBlt(sourceDevice to stampDevice);
    bitBlt(stampDevice to canvasDevice);
}


2) This is how the code will look like with my idea:

KisBrushStamp::createStamp(information)
{
    return brushManipulationChainStamp(information);
}

KisPencilStamp::createStamp(information)
{
    return pencilManipulationChainStamp(information);
}

...
...
resources::currentStamp = registry->stamp("brushstamp"); <--- call done, for
                                          example, througth a nice UI.
...
...

KisDrawingOp::paintAt(information)
{
    stampDevice = currentStamp->createStamp(information); <--- currentStamp
                                          builds directly a complete stamp!

    stampDevice->setColor(currentColor);  <--- this can even done directly in
                                               create Stamp!

    bitBlt(stampDevice to canvasDevice);
}

KisCloneOp::paintAt(information)
{
    stampDevice = currentStamp->createStamp(information); <--- currentStamp
                                          builds directly a complete stamp!

    bitBlt(sourceDevice to stampDevice);
    bitBlt(stampDevice to canvasDevice);
}


Emanuele

PS: by the way this integrates perfectly with boud new code.


More information about the kimageshop mailing list