Review Request 109614: Fix transition between normal and hover images

Aurélien Gâteau agateau at kde.org
Thu Mar 21 13:01:43 GMT 2013



> On March 21, 2013, 12:52 p.m., Frank Reininghaus wrote:
> > Thanks Aurélien for your efforts to fix this! Looks good, I would just rename pix1 and pix2 to pixmap1 and pixmap2 to be consistent with other code (we mostly try to not abbreviate variable names).
> > 
> > The comment is indeed a bit long. Maybe we could just say "Linear interpolation between m_pixmap and m_hoverPixmap. Note that this cannot be achieved by painting m_hoverPixmap over m_pixmap, even if the opacities are adjusted. For details see (link to review request, blog, or something like that)".
> > 
> > I'm looking forward to your blog post about this :-)

I adjusted the changes as you requested. Here is the details regarding the linear interpolation:

"""
Linear interpolation between pixA and pixB using value v.

This cannot be done with:

1. painter.drawPixmap(0, 0, pixA);
2. painter.setOpacity(v);
3. painter.drawPixmap(0, 0, pixB);

Doing this paints pixB over pixA, meaning any not-fully opaque pixel of pixB
will show pixA pixels, even when v is close to 1.0.

This is not linear interpolation either:

1. painter.setOpacity(1.0 - v);
2. painter.drawPixmap(0, 0, pixA);
3. painter.setOpacity(v);
4. painter.drawPixmap(0, 0, pixB);

Here is why:

Let's assume our background is opaque black and our pixmaps are fully opaque
(it simplifies the math but still expose the flaw).

Using the linear interpolation formula [1], the result of interpolating two
opaque images over an opaque black background should be (where c() is either
the red, green or blue component of an image):

  c(pixB) * v  +  c(pixA) * (1 - v)

After line 2, the widget shows pixA alpha blend on top of opaque black using
the SourceOver formula [2] with k = 1 - v. The temporary appearance is thus:

  c(tmp) = c(pixA) * (1 - v)  +  c(black) * (1 - (1 - v))
         = c(pixA) * (1 - v)

After line 4, the widget shows pixB alpha-blended on top of tmp with k = v. The
final pixels are thus:

  c(final) = c(pixB) * v  +  c(tmp) * (1 - v)
           = c(pixB) * v  +  c(pixA) * (1 - v) * (1 - v)
           = c(pixB) * v  +  c(pixA) * (1 - v)^2

Which is different from:

             c(pixB) * v  +  c(pixA) * (1 - v)

It goes even more wrong when the pixmaps are not fully opaque, because the
SourceOver formula does not do a linear interpolation between foreground and
background: the interpolation takes the opacity of the images into account.

To get the correct result, we paint each images on a separate transparent
buffer with appropriate opacity, then blend the buffers using
CompositionMode_Plus and finally paint the result on the widget.

-- Formulas --
[1] Linear interpolation, painting fg over bg with a factor of k:

a(result) = a(fg) * k + a(bg) * (1 - k)
c(result) = c(fg) * k + c(bg) * (1 - k)

[2] SourceOver formula, painting fg over bg with an opacity of k, simplified
for the case where bg is fully opaque:

a(result) = 1
c(result) = c(fg) * a(fg) * k  +  c(bg) * (1 - a(fg) * k)

And if fg is fully opaque as well:

a(result) = 1
c(result) = c(fg) * k  +  c(bg) * (1 - k)
"""


- Aurélien


-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
http://git.reviewboard.kde.org/r/109614/#review29623
-----------------------------------------------------------


On March 20, 2013, 5:44 p.m., Aurélien Gâteau wrote:
> 
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> http://git.reviewboard.kde.org/r/109614/
> -----------------------------------------------------------
> 
> (Updated March 20, 2013, 5:44 p.m.)
> 
> 
> Review request for Dolphin.
> 
> 
> Description
> -------
> 
> This is a follow-up to https://git.reviewboard.kde.org/r/108858/ . It has been brought to my attention the painting code I wrote was still wrong: when you mouse over items, the transition between the normal and hover images is not as smooth as it should be. Especially at the end, one has the feeling of a "bump".
> 
> I did quite a bit of debugging on that bug and wrote the result of my research in a huge comment. It may be too big, I am happy to remove it. I am probably going to blog about this anyway, since the hunt for that bug was interesting.
> 
> 
> Diffs
> -----
> 
>   dolphin/src/kitemviews/kstandarditemlistwidget.cpp fcd0520457dc2cbe3ca1435129e20a0b9dfb28fc 
> 
> Diff: http://git.reviewboard.kde.org/r/109614/diff/
> 
> 
> Testing
> -------
> 
> Moved the mouse over normal and hidden items, transition is smooth.
> 
> 
> Thanks,
> 
> Aurélien Gâteau
> 
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.kde.org/mailman/private/kfm-devel/attachments/20130321/42e87ec2/attachment.htm>


More information about the kfm-devel mailing list