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