[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kimageshop
Subject:    Re: A first part of the layers/masks patch
From:       Sven Langkamp <sven.langkamp () gmail ! com>
Date:       2009-09-29 0:10:45
Message-ID: 478b087a0909281710y34c66598h85ea88cc28986dde () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


On Fri, Sep 25, 2009 at 9:25 PM, Dmitry Kazakov <dimula73@gmail.com> wrote:

> What is done in the patch.
>
>
> 1) Now all the layers apply their own masks in a uniform way.
>
> How it was before:
> Every type of layer (paint, adjustment,etc) had it's own
> updateProjection() function. And EVERY layer implemented it's own
> cycle of applying masks. No need to say that they all differed. And
> most of them was broken, because they didn't take into account
> need/change rects of filters inside masks (at best).
>
> How it is now:
> updateProjection() and ALL the stuff about masks AND projections is
> moved to KisLayer. Specialized layer can operate with only a few
> functions those are not connected with a projection much. Every child
> can overload these functions:
>
> original() - returns a paint device where the layer stores it's
> image. NOTE: This is not the same with projection() as the latter one
> includes original() with all the masks applied.
>
> repaintOriginal() - called by updateProjection when original should be
> repainted.
>
> OPTIONAL:
> A layer CAN (not should) overload:
>
> needProjection() - if a layer needs an always-in-memory projection
> (e.g. KisPaintLayer needs one for indirect painting)
>
> copyOriginalToProjection() - used in couple with the previous one. A
> layer can enhance original during painting on a projection
> (e.g. indirect painting, see KisPaintDevice's method)
>
>
> This all means that a KisLayer's child shouldn't do any work to create
> a projection. It's created by KisLayer in a deferred way (when masks
> are present)
>
> Masks application strategy changed too (and quite much).
> Now changeRect()/needRect() functions are part of KisNode. And before
> application of a mask-stack we first get to know what need rect we
> want to copy from original() device.
>
> Rect calculating algorithm is quite overwhelming. It's implemented in
> two functions: masksChangeRect and masksNeedRect.
> First we get a change rect of a DESTINATION PROJECTION with a first
> function in a bottom-up(!) way. Then we calculate needRects for all
> the masks in a top-down(!) way with a second function, and by the end
> of this process we get a rect that we should copy from original()
> device to a temporary device for applying filters.
>
> BUGFIX:
> This part of a patch fixes a bug with a blur-filter-mask. In current
> version  you simply you get a slack if you paint on a layer with
> blur-mask present (i'm not sure you can check it up now, because
> blur-filter has an internal bug - it writes the result to the source
> instead of destination).
>
>
> 2) The second task for this patch was to unify adjustment and
> generator layers. The point is, they both use selections, that means
> they both should work in the same way.
>
> How it was before:
> KisAdjustmentLayer and KisGeneratorLayer had code duplications for
> selections stuff.
>
> How it is now:
> All the selection-related stuff is moved to a separate class -
> KisSelectionBasedLayer. Both problematic classes are derived from this
> base class. Speaking truly, KisAdjustmentLayer class has very few code
> inside now.
>
> BUGFIX:
> Selections on selection based layers was not working at all
> before. Now the the code applies selections (if you manage to
> create one ;) (see * for more)) to the layers well.
>
>
> 3) The third task was to clean masks classes. We had much code
> duplication there too. Most duplications and misuses was connected to
> selections (again).
>
> How it was before:
> KisFilterMaks, KisGeneratorMask, KisTransparencyMask - they all had
> their own implementation
>
> How it is now:
> All the selection-related stuff is moved to KisMask class. Here is an
> extract form a commit message:
>
>     Refactoring for masks
>
>     Now masks utilize selections in a uniform way. KisMask is the only
>     place that knows anything about mask's selection[0]. It's descendant's
> do
>     very simple task, they just decorate the rect with the desired
>     effect[1]. The task made by KisTransparencyMask fell back to even more
>     trivial routine - it just needs to copy source image to destination,
>     without any modifications[2].
>
>     Another significant change accumulated by this commit is a small
>     cleanup of KisMaskManager. There are still many FIXME's for it. The
>     most annoying is code duplication [3] of KActions for masks.
>
>     [0] - KisMask::apply()
>     [1] - virtual KisMask::decorateRect()
>     [2] - KisTransparencyMask::decorateRect()
>     [3] - KisMaskManager's actions for mask functions are duplicated in
>     KisLayerBox.
>
> As you can see, this commit accumulates some cleanups for
> KisMaskManager too. Most of them remove code duplications and uniform
> the code. More than that [and this is the only place where i worry
> about the patch] this fix adds a new method(!) to KoDocument. It's
> called undoLastCommand() - that is an equivalent to a user-undo
> command. It is added to be able to cancel creation of an filter mask
> in case a user presses 'Cancel' button in a creation dialog. Please
> review this change!
>
> BUGFIXES:
> - cancelling creation of the filter mask now do not break undo stack
> - selections (see *) on filter masks work well now
>
>
> 4) Cleaning selections infrastructure, made me create a benchmark for
> different selection application algorithms. This benchmark is placed
> in ./image/tests/kis_filter_selections_benchmark.cpp. I wrote about it
> already here.
>
>
> *) Still present bugs:
>
> a) [the worst one] Painting on any alpha mask do not work because of
> alpha() colorspace issue i was described before in this maillist. You
> can paint if your mask is transparent, but the brush isn't. This is
> not an issue of an algorithm. This is an issue of the alpha()
> colorspace and the fact that we use brush's alpha channel for painting
> alpha image-channel (tha latter assumption is completely wrong(!)).
>
> Solution: Brush's dab should use grayscale colorspace during painting
> on alpha-mask/selection. KisSelection should use grayscale, or a
> special alpha_special() colorspace to work with grayscale channel of a
> dab.
>
> b) Vector selection tools DO NOT work on masks (And i'm not sure they
> work on adjustment layers). The reason of the first fact (i think) is
> that KisSelectionToolHelper class uses KisLayerSP type for internal
> storage of a paint device. It should be changed to KisNodeSP to fix
> that (of course alongside some other changes in logics of this class)
>
> a),b) => c) There is no(!) way to paint on alpha-channels/masks
> currently. You simply CAN'T change the mask you created.
>
> The only way to create a mask now is the following:
>     i) make a vector selection first
>     ii) create a  mask - it'll derive this selection for it's own
>
> [some minor bugs not dependent on the patch]
> d) Blur filter works wrong. It writes filtered image to the source
> device instead of the destination one
>
> e) Drag&Drop is broken in KisLayerBox. Just try to change an order of
> masks with a mouse - you can easily lift it up above the root
> layer. Of course,  your next action will cause krita to crash.
>
> f) Curves filter DO NOT(!) work. I guess, there is some bug in
> KoColorTransformation as every curve works as a brightness/contrast
> curve instead of a channel curve. Just try it out!
>
>
> [some design bugs]
> g) KisNodeManager::allowAsChild uses some silly string comparison
> algorithm. Why?! Every node has a specially designed method for this!
>
> h) KActions for mask-manipulation functions are duplicated in
> KisMaskManager and in KisLayerBox. They must be moved to
> KisMaskManager.
>
> PS:
> btw, a,b,c,d,e,f are good, well-fed release blockers.
>

Painting on masks is a bit weird as now the meaning of brush and eraser is
reversed. So before the patch I could paint transparency with the brush, now
I have to use the eraser.

Also painting on mask causes some artifacts:
http://img23.imageshack.us/img23/3918/kritafiltermask.png

[Attachment #5 (text/html)]

<div class="gmail_quote">On Fri, Sep 25, 2009 at 9:25 PM, Dmitry Kazakov <span dir="ltr">&lt;<a \
href="mailto:dimula73@gmail.com">dimula73@gmail.com</a>&gt;</span> wrote:<br><blockquote \
class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt \
0.8ex; padding-left: 1ex;"> What is done in the patch.<br><br><br>1) Now all the layers apply \
their own masks in a uniform way.<br><br>How it was before:<br>Every type of layer (paint, \
adjustment,etc) had it&#39;s own<br>updateProjection() function. And EVERY layer implemented \
it&#39;s own<br>

cycle of applying masks. No need to say that they all differed. And<br>most of them was broken, \
because they didn&#39;t take into account<br>need/change rects of filters inside masks (at \
best).<br><br>How it is now:<br>updateProjection() and ALL the stuff about masks AND \
projections is<br>

moved to KisLayer. Specialized layer can operate with only a few<br>functions those are not \
connected with a projection much. Every child<br>can overload these \
functions:<br><br>original() - returns a paint device where the layer stores it&#39;s<br>

image. NOTE: This is not the same with projection() as the latter one<br>includes original() \
with all the masks applied.<br><br>repaintOriginal() - called by updateProjection when original \
should be<br>repainted.<br><br> OPTIONAL:<br>
A layer CAN (not should) overload:<br><br>needProjection() - if a layer needs an \
always-in-memory projection<br>(e.g. KisPaintLayer needs one for indirect \
painting)<br><br>copyOriginalToProjection() - used in couple with the previous one. A<br>

layer can enhance original during painting on a projection<br>(e.g. indirect painting, see \
KisPaintDevice&#39;s method)<br><br><br>This all means that a KisLayer&#39;s child \
shouldn&#39;t do any work to create<br>a projection. It&#39;s created by KisLayer in a deferred \
way (when masks<br>

are present)<br><br>Masks application strategy changed too (and quite much).<br>Now \
changeRect()/needRect() functions are part of KisNode. And before<br>application of a \
mask-stack we first get to know what need rect we<br>

want to copy from original() device.<br><br>Rect calculating algorithm is quite overwhelming. \
It&#39;s implemented in<br>two functions: masksChangeRect and masksNeedRect.<br>First we get a \
change rect of a DESTINATION PROJECTION with a first<br>

function in a bottom-up(!) way. Then we calculate needRects for all<br>the masks in a \
top-down(!) way with a second function, and by the end<br>of this process we get a rect that we \
should copy from original()<br>device to a temporary device for applying filters.<br>

<br>BUGFIX:<br>This part of a patch fixes a bug with a blur-filter-mask. In current<br>version  \
you simply you get a slack if you paint on a layer with<br>blur-mask present (i&#39;m not sure \
you can check it up now, because<br>

blur-filter has an internal bug - it writes the result to the source<br>instead of \
destination).<br><br><br>2) The second task for this patch was to unify adjustment \
and<br>generator layers. The point is, they both use selections, that means<br>

they both should work in the same way.<br><br>How it was before:<br>KisAdjustmentLayer and \
KisGeneratorLayer had code duplications for<br>selections stuff.<br><br>How it is now:<br>All \
the selection-related stuff is moved to a separate class -<br>

KisSelectionBasedLayer. Both problematic classes are derived from this<br>base class. Speaking \
truly, KisAdjustmentLayer class has very few code<br>inside now.<br><br>BUGFIX:<br>Selections \
on selection based layers was not working at all<br>

before. Now the the code applies selections (if you manage to<br>create one ;) (see * for \
more)) to the layers well.<br><br><br>3) The third task was to clean masks classes. We had much \
code<br>duplication there too. Most duplications and misuses was connected to<br>

selections (again).<br><br>How it was before:<br>KisFilterMaks, KisGeneratorMask, \
KisTransparencyMask - they all had<br>their own implementation<br><br>How it is now:<br>All the \
selection-related stuff is moved to KisMask class. Here is an<br>

extract form a commit message:<br><br>    Refactoring for masks<br><br>    Now masks utilize \
selections in a uniform way. KisMask is the only<br>    place that knows anything about \
mask&#39;s selection[0]. It&#39;s descendant&#39;s do<br>

    very simple task, they just decorate the rect with the desired<br>    effect[1]. The task \
made by KisTransparencyMask fell back to even more<br>    trivial routine - it just needs to \
copy source image to destination,<br>

    without any modifications[2].<br><br>    Another significant change accumulated by this \
commit is a small<br>    cleanup of KisMaskManager. There are still many FIXME&#39;s for it. \
The<br>    most annoying is code duplication [3] of KActions for masks.<br>

<br>    [0] - KisMask::apply()<br>    [1] - virtual KisMask::decorateRect()<br>    [2] - \
KisTransparencyMask::decorateRect()<br>    [3] - KisMaskManager&#39;s actions for mask \
functions are duplicated in<br>    KisLayerBox.<br>

<br>As you can see, this commit accumulates some cleanups for<br>KisMaskManager too. Most of \
them remove code duplications and uniform<br>the code. More than that [and this is the only \
place where i worry<br>about the patch] this fix adds a new method(!) to KoDocument. \
It&#39;s<br>

called undoLastCommand() - that is an equivalent to a user-undo<br>command. It is added to be \
able to cancel creation of an filter mask<br>in case a user presses &#39;Cancel&#39; button in \
a creation dialog. Please<br>review this change!<br>

<br>BUGFIXES:<br>- cancelling creation of the filter mask now do not break undo stack<br>- \
selections (see *) on filter masks work well now<br><br><br>4) Cleaning selections \
infrastructure, made me create a benchmark for<br>

different selection application algorithms. This benchmark is placed<br>in \
./image/tests/kis_filter_selections_benchmark.cpp. I wrote about it<br>already \
here.<br><br><br>*) Still present bugs:<br><br>a) [the worst one] Painting on any alpha mask do \
not work because of<br>

alpha() colorspace issue i was described before in this maillist. You<br>can paint if your mask \
is transparent, but the brush isn&#39;t. This is<br>not an issue of an algorithm. This is an \
issue of the alpha()<br>colorspace and the fact that we use brush&#39;s alpha channel for \
painting<br>

alpha image-channel (tha latter assumption is completely wrong(!)).<br><br>Solution: \
Brush&#39;s dab should use grayscale colorspace during painting<br>on alpha-mask/selection. \
KisSelection should use grayscale, or a<br> special alpha_special() colorspace to work with \
grayscale channel of a<br> dab.<br><br>b) Vector selection tools DO NOT work on masks (And \
i&#39;m not sure they<br>work on adjustment layers). The reason of the first fact (i think) \
is<br>that KisSelectionToolHelper class uses KisLayerSP type for internal<br>

storage of a paint device. It should be changed to KisNodeSP to fix<br>that (of course \
alongside some other changes in logics of this class)<br><br>a),b) =&gt; c) There is no(!) way \
to paint on alpha-channels/masks<br>currently. You simply CAN&#39;T change the mask you \
created.<br>

<br>The only way to create a mask now is the following:<br>    i) make a vector selection \
first<br>    ii) create a  mask - it&#39;ll derive this selection for it&#39;s own<br><br>[some \
minor bugs not dependent on the patch]<br>

d) Blur filter works wrong. It writes filtered image to the source<br>device instead of the \
destination one<br><br>e) Drag&amp;Drop is broken in KisLayerBox. Just try to change an order \
of<br>masks with a mouse - you can easily lift it up above the root<br>

layer. Of course,  your next action will cause krita to crash.<br><br>f) Curves filter DO \
NOT(!) work. I guess, there is some bug in<br>KoColorTransformation as every curve works as a \
brightness/contrast<br>curve instead of a channel curve. Just try it out!<br>

<br><br>[some design bugs]<br>g) KisNodeManager::allowAsChild uses some silly string \
comparison<br>algorithm. Why?! Every node has a specially designed method for this!<br><br>h) \
KActions for mask-manipulation functions are duplicated in<br>

KisMaskManager and in KisLayerBox. They must be moved to<br>KisMaskManager.<br><br>PS:<br>btw, \
a,b,c,d,e,f are good, well-fed release blockers.<br></blockquote><div><br>Painting on masks is \
a bit weird as now the meaning of brush and eraser is reversed. So before the patch I could \
paint transparency with the brush, now I have to use the eraser.<br> <br>Also painting on mask \
causes some artifacts:<br><a \
href="http://img23.imageshack.us/img23/3918/kritafiltermask.png">http://img23.imageshack.us/img23/3918/kritafiltermask.png</a> \
<br></div></div><br>



_______________________________________________
kimageshop mailing list
kimageshop@kde.org
https://mail.kde.org/mailman/listinfo/kimageshop


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic