PDA

View Full Version : QSvgRenderer::boundsOnElement returns incorrect QRectF



lfranchi
31st July 2007, 23:00
Hello all,

I am trying to use QSvgRenderer to first render a static SVG in a QGraphicsScene and then, using QSvgRenderer::boundsOnElement, draw custom text inside elements that are specified in the svg.

My problem is that the QRect that boundsOnElement returns does *not* actually correspond to the element location in the svg, and so when I draw my text in the rect, it is drawn in the incorrect place. If you look at the attached screenshot, notice the following:

1) the widget I am talking about is the dark-grey colored box in the center of Amarok, at the bottom of the picture.
2) i have emphasized the 3 elements that I am talking about in this case, notice the 3 very bold/colorful rectangles in the middle of the svg.
3) notice at the *very bottom* of the picture, the text "Athlete". that text is supposed to be inside the first colored rectangle.

also, if you look at the console output, the following catches the eye:

the bounds of the topmost element (blue, where "athlete" should go), is (270, 412 285x9). this is the rect returned by QSvgRenderer::boundsOnElement. the size of the widget, as returned by QSvgRenderer::size, is (554, 230).

now, it doesn't even make sense for the position of the element to be outside the reported size of the widget. can anyone help shed some light on this, or point to what fundamental thing i'm doing wrong?

thanks,
leo

marcel
31st July 2007, 23:28
How do you render the svg?
I mean, which one of the functions do you use?
Also, what does matrixForElement for that element returns? Could you copy that and post it?

BTW, the quality of your screenshot is pretty low, so I cannot make out the details...

Regards

lfranchi
1st August 2007, 00:11
How do you render the svg?
I mean, which one of the functions do you use?
Also, what does matrixForElement for that element returns? Could you copy that and post it?


It's a little complicated, but at the heart of it is a call to QSvgRenderer::drawPixmap.

The output of matrixForElement is thus:
matrixForElement: QMatrix(11=1 12=0 21=0 22=1 dx=-20.4364 dy=-382.362)

that seems to be the issue (the dy being -382.362 can't be good...), so at this point i'm not understanding what exactly is going on. How does the element matrix get changed/set to be like that? What does that mean?



BTW, the quality of your screenshot is pretty low, so I cannot make out the details...

Regards

sorry, it appears the forum software resizes large images and loses quality on the resize.

best,
leo

marcel
1st August 2007, 00:16
I assumed it would be the matrix.

The dx and dy components of the matrix mean translation( on the X and Y axes ).
The QSvgRenderer::boundsForElement states that the transformation matrix of the parents does not affect the bounding box.
So you get a bbox that is not mapped to the translated coordinate system in the svg.

All you have to do is to create a new QRectF that has x = bbox.x() + dx and y = bbox.y() + dy. This means that you translate the bounds to their real location.

I think you can use the return of boundsForElement. Just use QRectF::setX and QRectF::setY.


So, it should work...

EDIT: I am not familiar with QSvgRenderer::drawPixmap. Actually, I cannopt find it anywhere in the documentation. You must be referring to QPainter::draw pixmap. To render the svg you must have been using one of the QSvgRenderer::render methods.


Regards

lfranchi
1st August 2007, 00:35
Yes, that has fixed it. Thank you for the pointer! I had read through the API multiple times but didn't understand that the transformation matrix stuff completely.

Leo

marcel
1st August 2007, 00:38
Yes, that has fixed it. Thank you for the pointer! I had read through the API multiple times but didn't understand that the transformation matrix stuff completely.

Leo
No problem. You're welcome.

lfranchi
1st August 2007, 05:54
No problem. You're welcome.

Unfortunately I have run into another problem. I have now read up on the SVG transform spec etc, so i have a clearer idea of what the transform matrix is. Nevertheless, I am now trying to render a more complex vector shape (star) and am running into problems.

The matrices for the simple rectangular elements (which have text placed into them) are very similar to this:

matrixForElement: QMatrix(11=1 12=0 21=0 22=1 dx=-20.4364 dy=-382.362)

however, the matrix for the star element (which is right below the text rect, hence should have similar dx/dy values, is:

matrixForElement: QMatrix(11=0.193355 12=0 21=0 22=0.201225 dx=250.899 dy=104.113)

this of course means that if i do a translate( dx, dy) on the bounding rect, the text boxes will line up correctly, as foreseen, but the stars will go *the other way* and get even farther away. do you know if this is a problem with the svg, or am i doing some sort of rendering error?

note: if i do *not* add the translation to anything, both the stars and the text all are aligned correctly relative to each other, but are all position too far down, as in the original screenshot.

lfranchi
1st August 2007, 07:21
Disregard my last post, after much investigation the svg itself turned out to be at fault.

marcel
1st August 2007, 10:49
Unfortunately I have run into another problem. I have now read up on the SVG transform spec etc, so i have a clearer idea of what the transform matrix is. Nevertheless, I am now trying to render a more complex vector shape (star) and am running into problems.

The matrices for the simple rectangular elements (which have text placed into them) are very similar to this:

matrixForElement: QMatrix(11=1 12=0 21=0 22=1 dx=-20.4364 dy=-382.362)however, the matrix for the star element (which is right below the text rect, hence should have similar dx/dy values, is:

matrixForElement: QMatrix(11=0.193355 12=0 21=0 22=0.201225 dx=250.899 dy=104.113)this of course means that if i do a translate( dx, dy) on the bounding rect, the text boxes will line up correctly, as foreseen, but the stars will go *the other way* and get even farther away. do you know if this is a problem with the svg, or am i doing some sort of rendering error?

note: if i do *not* add the translation to anything, both the stars and the text all are aligned correctly relative to each other, but are all position too far down, as in the original screenshot.

As opposed to the rectangle element, the star also has a rotation induced to it.
This is not the reason for the unexplained offset, however.
I didn't mentioned earlier, but you should take in account the scaling and rotation when computing the bounding boxes.

Regards