[Panel-devel] rfc: Plasma::Theme and Plasma::Svg
Zack Rusin
zack at kde.org
Tue Mar 6 21:40:10 CET 2007
On Tuesday 06 March 2007 13:46, Aaron J. Seigo wrote:
<snip>
> 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.
Sounds like a great idea.
> 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
Right on.
> - paint( QPainter*, const QRect& )
> pretty obvious =)
If Svg has a native size then I think the natural paint method for it would
simply take a point. Otherwise if you'd like to extand to the whole rect
(which will imply rerendering on the fly anyway) I'd suggest following the
Qt's scenario where you both accept the source rectangle and destination
rectangle. But yeah, the QPoint method would be enough.
> - resize( int width, int height )
> also pretty obvious
> - resize( const QSize& size )
> even more obvious ;)
Neat.
> 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}
Damn, I have to spoil the party =) This won't work. This won't work because
you accept an arbitrary painter and try this experiment in widget of your
choice:
QSvgRender r("file.svg");
QPixmap px(100, 100);
QPainter p(&px);
r.render(&p);
p.end();
p.begin(this);
p.setRenderHint(QPainter::Antialiasing);
p.scale(2, 2);
p.drawPixmap(0, 0, px);
p.end();
Spot Waldo? :) When rendering the pixmap on the widget the painter is scaled
so we're upscaling the pixmap itself which will produce very ugly results.
Even worse when you think about any other transformations besides scaling.
By stuffing pixmap into cache while using the filename/size as the key this is
the behavior you'll get. The good news is that I did the code to correctly
cache svg's in an application global fashion in QGraphicsSvgItem so it's not
a hard problem to get it right (it does involve a bit of math though but I'm
here :) ). I guess Plasma::Svg will be very similar to QGraphicsSvgItem
without the QGraphicsItem inheritance and with some nice code to mix it in
with the rest of Plasma contents. I probably should have created
QSvgCacheRenderer or maybe even adding caching to QSvgRenderer instead of
adding it only to QGraphicsSvgItem. Oh, well, maybe in Qt 4.4 ;)
> 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.
Sounds like a great plan. I'm not sure how well the refcounting of pixmaps
would work, but it's not a burning thing.
z
More information about the Panel-devel
mailing list