[Panel-devel] rfc: Plasma::Theme and Plasma::Svg

Aaron J. Seigo aseigo at kde.org
Tue Mar 6 19:46:21 CET 2007


hey all..

looking at the use patterns in ksysguard, krunner and now plasma for QSvg this 
seems to be the common approach:

- load the svg from disk
- on paint, render the svg into a pixmap and hold on to that, blit the pixmap
- on resize, mark the cached pixmap as dirty, causing a re-render on next 
paint

this is because rendering svg obviously takes more time than simply blitting 
an image

the other concern is that QSvg can take a good amount of memory to build the 
render tree, etc.. so sharing renderers is a good idea; and deleting them 
when not needed anymore is even better.

there are two other assumptions that went into my thinking on this that 
reflect the current state of panels and desktop widgets in kde and other 
desktops:

 - items will be long-lived but rarely change size
 - many items will share identical graphical elements, e.g. widget and button 
backgrounds

i sat down last night and put together a design that will provide for these 
use cases to avoid duplicating this pattern over and over in the code.

Plasma::Svg will provide the following public methods:

- Svg(const QString& imagePath, const QSize& size)
	constructor that takes a path to be used with Plasma::Theme
- paint( QPainter*, const QRect& )
	pretty obvious =)
- resize( int width, int height )
	also pretty obvious
- resize( const QSize& size )
	even more obvious ;)

so one would simply do:

Plasma::Svg* bg = Plasma::Svg( "dialog/background", QSize( 400, 250 ) );

and in the paint method:

QPainter p( this );
bg->paint( &p, rect() )

to facilitate this, Plasma::Theme will be changed to provide a singleton 
pattern, e.g. Theme* self().

what i haven't decided yet, is whether we should check the rect in paint() 
against the current size and assume that if the rect != rect() that a resize 
is implied. the usual case will be to call resize() in the painting item's 
resizeEvent() however, so i don't know if this will buy us anything in 
practice. at this point i'm taking a wait-and-see-approach on that.

the pixmaps will be stored in a QPixmapCache for use throughout the app. 
therefore, if more than one instance of the same Plasma::Theme image path 
with the same rendering size is available, there should be no need to hit 
disk, parse or render the svg. woo! item keys will be constructed this way:

  ${IMAGE_PATH}_${WIDTH}_${HEIGHT}

internally, Plasma::Svg will have a ref-counted shared struct of data 
containing:

 - refcount on the QPixmapCache entry
 - QSvgRenderer. this should prevent multiple instantiations of the renderer.

profiling should later show if/when/how the shared renderer should be 
instantiated and removed. e.g. it may make sense to create the renderer and 
after a certain amount of time w/out calls to resize to delete it to conserve 
memory.

-- 
Aaron J. Seigo
humru othro a kohnu se
GPG Fingerprint: 8B8B 2209 0C6F 7C47 B1EA  EE75 D6B7 2EB1 A7F1 DB43

Full time KDE developer sponsored by Trolltech (http://www.trolltech.com)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/panel-devel/attachments/20070306/228a7f13/attachment.pgp 


More information about the Panel-devel mailing list