On Sunday 14 February 2010 15:33:04 Marco Martin wrote: > for a really generic thing, i fear something would be needed at the level > of QSvg. > and always will have some approximate results. > QSvg should do something like: > -when rendering a shape, always adjust its bounding rect to the pixel grid. > -if it has a border adjust the bounding rect of the border instead > would probably yeld slightly better, even if not perfect results.
I'm not sure if I see what you're saying because it seems that you're advocating doing the opposite of what you're trying to do =) You can't snap to a pixel grid, that's because SVG's aren't created on a pixel grid, e.g if the viewport is 0.5, 0.5 to 31.5, 31.5 and we snap it to 1,1, 32,32 then the exact problem that you're trying to prevent will happen (pixel bleeding). SVG's, especially in KDE (due to combining multiple renderings in one SVG file) virtually never have integer coordinates. I think the problem that you're trying to prevent could be reformulated as "don't render SVG's in non-native viewports" as the native viewport is likely the only one that the SVG is definitely looking good at. And for that Plasma does have enough info and doesn't need QtSvg to do anything. The idea is that the rendering bounds need to be even uniform multiples of the scaling factor. In a email hacking form: //to and from are /always/ 0 <= val <= 1 qreal closestDistance(qreal to, qreal from) { qreal a = to - from; if (qFuzzyCompare(to, from)) return 0; else if ( to > from ) { qreal b = to - from - 1; return (qAbs(a) > qAbs(b)) ? b : a; } else { qreal b = 1 + to - from; return (qAbs(a) > qAbs(b)) ? b : a; } } QRectF makeUniform(const QRect &orig, const QRect &dst) { QRectF res(dst); qreal div_w = dst.width() / orig.width(); qreal div_h = dst.height() / orig.height(); qreal div_x = dst.x() / orig.x(); qreal div_y = dst.y() / orig.y(); //horizontal snap if (!qFuzzyIsNull(div_x) && !qFuzzyCompare(div_w, div_x)) { qreal rem_orig = orig.x() - (floor(orig.x())); qreal rem_dst = dst.x() - (floor(dst.x())); qreal offset = closestDistance(rem_dst, rem_orig); res.adjust(offset/div_w, 0, 0, 0); } //vertical snap if (!qFuzzyIsNull(div_y) && !qFuzzyCompare(div_h, div_y)) { qreal rem_orig = orig.y() - (floor(orig.y())); qreal rem_dst = dst.y() - (floor(dst.y())); qreal offset = closestDistance(rem_dst, rem_orig); res.adjust(0, offset/div_h, 0, 0); } } res.adjust might not need the division of offset by respectively div_w and div_h but it probably would look better with divisor (verification would be needed). and then in Plasma::Theme::paint you'd call makeUniform with contentsRect and QSvgRenderer::boundsForElement for the element that you're rendering to get the properly adjusted contentsRect. I *think* that should sharpen up all SVG rendering in Plasma especially at smaller resolution, but someone would have to test this. The other solution would be to impose restrictions on viewport coordinates inside the actual SVG's that plasma is using (while lot less flexible, would likely offer better results), e.g. always integer based. z _______________________________________________ Plasma-devel mailing list Plasma-devel@kde.org https://mail.kde.org/mailman/listinfo/plasma-devel