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