Transparent background for widgets in KHTML

Germain Garand germain at ebooksfrance.org
Fri Mar 14 00:12:20 GMT 2008


Le jeudi 13 mars 2008, Rafael Fernández López a écrit :
> The only thing I can't understand is, why we need a method that needs a
> sub-rectangle. 

because we do not repaint widgets in whole, but only dirty parts.
The paint buffer is sized to the widget, but we only erase the rectangle we'll 
repaint.

Anyway, please forget what I said about moving things to PaintBuffer.
I only managed to confuse you and I realized it's not really needed (see 
below).

> I guess what we need to pass to this method is the widget 
> pixmap (which is a pixmap with the widget size) and do the next:
>
> 1. Set Alpha channel to 100% transparency
> 2. Fill with Qt::transparent
> 3. Restore Alpha channel
> 4. Render widget
>
> From we have been talking on #khtml, it seems that doing this is more or
> less the same as setting a mask. That depends now:
>
> - We could still go through the mask strategy, even knowing that it is
> slower (the other alternatives that could work are in the same terms of
> slowness). This one works for sure, the patch works.
>

I certainly would not be bringing this issue if the difference in speed was in 
the same order of magnitude. I don't think it is!

Please try the attached program and see for yourself.
Here is an average output on my system:

Iterating 200 times.
fill pixmap: 5 ms
set mask: 4703 ms
fillRect + CompositionMode_Source: 2 ms
using Qt 4.3.1

> - We could try to do the previous steps, and see if it works. From what
> Fredrik, said, it seems this would be more or less as slow as setting the
> mask.

I realized the fill method to use can be disambiguated by testing 
hasAlphaChannel(). So changes can be kept to a minimum in copyWidget ; 
something like:

         pm = PaintBuffer::grab(widget->size());
-        QPainter pp(pm);
-        pp.setCompositionMode(QPainter::CompositionMode_Clear);
-        pp.eraseRect(r);
-        pp.end();
+        if (!pm->hasAlphaChannel()) {
+            pm->fill(Qt::transparent);
+        } else {
+            QPainter pp(pm);
+            pp.setCompositionMode( QPainter::CompositionMode_Source );
+            pp.fillRect(r, Qt::transparent);
+        }
         d = pm;

should work... it does seem to work here at least.

> Since I don't know what paintbuffer does, if it is applied to all pixmaps
> or not, and it has no documentation... Well, if this class is used for
> every pixmap, the lose in time is not critical.

PaintBuffer stores one pixmap (or several for CSS opacity layers) for an 
amount of time, to handle repetitive painting.

so yes, setting the mask there would mitigate the speed issue, but it would 
still matter, as the pixmap is only reused if it can satisfy the next 
requested size. So if the requested sizes are quickly changing, the 
PaintBuffer doesn't make much of a difference.

Greetings,
Germain
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tst.cpp
Type: text/x-c++src
Size: 855 bytes
Desc: not available
URL: <https://mail.kde.org/mailman/private/kfm-devel/attachments/20080314/8ceaab10/attachment.cpp>


More information about the kfm-devel mailing list