1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-19 09:54:15 +01:00

PFD: split the compass band to parts to fit the texture limit

On older graphics cards the texture size limit
may be smaller than the compass band width,
QML downscales the element to fit the texture.

To avoid this, split compass band to tiles.

Added parameter like hslice=2:8 to svg image provider
and SvgElementImage.
This commit is contained in:
Dmytro Poplavskiy 2012-09-11 15:16:58 +10:00
parent 4cc13c9eea
commit 18a9ad3aa8
4 changed files with 111 additions and 26 deletions

View File

@ -0,0 +1,37 @@
import Qt 4.7
import "."
Item {
id: sceneItem
property variant sceneSize
SvgElementImage {
id: compass
elementName: "compass"
sceneSize: sceneItem.sceneSize
clip: true
x: scaledBounds.x * sceneItem.width
y: scaledBounds.y * sceneItem.height
//anchors.horizontalCenter: parent.horizontalCenter
//split compass band to 8 parts to ensure it doesn't exceed the max texture size
Row {
anchors.centerIn: parent
//the band is 540 degrees wide, AttitudeActual.Yaw is converted to -180..180 range
anchors.horizontalCenterOffset: -1*((AttitudeActual.Yaw+180+720) % 360 - 180)/540*width
Repeater {
model: 5
SvgElementImage {
id: compass_band
elementName: "compass-band"
sceneSize: background.sceneSize
hSliceCount: 5
hSlice: index
}
}
}
}
}

View File

@ -48,25 +48,9 @@ Rectangle {
anchors.centerIn: parent
}
SvgElementImage {
id: compass
elementName: "compass"
Compass {
anchors.fill: parent
sceneSize: background.sceneSize
clip: true
y: 12
anchors.horizontalCenter: parent.horizontalCenter
SvgElementImage {
id: compass_band
elementName: "compass-band"
sceneSize: background.sceneSize
anchors.centerIn: parent
//the band is 540 degrees wide, AttitudeActual.Yaw is converted to -180..180 range
anchors.horizontalCenterOffset: -1*((AttitudeActual.Yaw+180+720) % 360 - 180)/540*width
}
}
SpeedScale {

View File

@ -4,11 +4,26 @@ Image {
id: sceneItem
property variant sceneSize
property string elementName
property string svgFileName : "pfd.svg"
property string svgFileName: "pfd.svg"
property int vSlice: 0
property int vSliceCount: 0
property int hSlice: 0
property int hSliceCount: 0
property variant scaledBounds: svgRenderer.scaledElementBounds(svgFileName, elementName)
sourceSize.width: Math.round(sceneSize.width*scaledBounds.width)
sourceSize.height: Math.round(sceneSize.height*scaledBounds.height)
Component.onCompleted: source = "image://svg/"+svgFileName+"!"+elementName
Component.onCompleted: {
var params = ""
if (hSliceCount > 1)
params += "hslice="+hSlice+":"+hSliceCount
if (vSliceCount > 1)
params += "vslice="+vSlice+":"+vSliceCount
if (params != "")
params = "?" + params
source = "image://svg/"+svgFileName+"!"+elementName+params
}
}

View File

@ -67,12 +67,23 @@ QSvgRenderer *SvgImageProvider::loadRenderer(const QString &svgFile)
}
/**
requestedSize is realted to the whole svg file, not to specific element
*/
Supported id format: fileName[!elementName[?parameters]]
where parameters may be:
vslice=1:2;hslice=2:4 - use the 3rd horizontal slice of total 4 slices, slice numbering starts from 0
requestedSize is related to the whole element size, even if slice is requested.
usage:
Image {
source: "image://svg/pfd.svg!world"
}
*/
QImage SvgImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
QString svgFile = id;
QString element;
QString parameters;
int separatorPos = id.indexOf('!');
if (separatorPos != -1) {
@ -80,6 +91,29 @@ QImage SvgImageProvider::requestImage(const QString &id, QSize *size, const QSiz
element = id.mid(separatorPos+1);
}
int parametersPos = element.indexOf('?');
if (parametersPos != -1) {
parameters = element.mid(parametersPos+1);
element = element.left(parametersPos);
}
int hSlicesCount = 0;
int hSlice = 0;
int vSlicesCount = 0;
int vSlice = 0;
if (!parameters.isEmpty()) {
QRegExp hSliceRx("hslice=(\\d+):(\\d+)");
if (hSliceRx.indexIn(parameters) != -1) {
hSlice = hSliceRx.cap(1).toInt();
hSlicesCount = hSliceRx.cap(2).toInt();
}
QRegExp vSliceRx("vslice=(\\d+):(\\d+)");
if (vSliceRx.indexIn(parameters) != -1) {
vSlice = vSliceRx.cap(1).toInt();
vSlicesCount = vSliceRx.cap(2).toInt();
}
}
if (size)
*size = QSize();
@ -114,8 +148,22 @@ QImage SvgImageProvider::requestImage(const QString &id, QSize *size, const QSiz
}
QRectF elementBounds = renderer->boundsOnElement(element);
int w = qRound(elementBounds.width() * xScale);
int h = qRound(elementBounds.height() * yScale);
int elementWidth = qRound(elementBounds.width() * xScale);
int elementHeigh = qRound(elementBounds.height() * yScale);
int w = elementWidth;
int h = elementHeigh;
int x = 0;
int y = 0;
if (hSlicesCount > 1) {
x = (w*hSlice)/hSlicesCount;
w = (w*(hSlice+1))/hSlicesCount - x;
}
if (vSlicesCount > 1) {
y = (h*(vSlice))/vSlicesCount;
h = (h*(vSlice+1))/vSlicesCount - y;
}
QImage img(w, h, QImage::Format_ARGB32_Premultiplied);
img.fill(0);
@ -124,12 +172,13 @@ QImage SvgImageProvider::requestImage(const QString &id, QSize *size, const QSiz
QPainter::Antialiasing |
QPainter::SmoothPixmapTransform);
renderer->render(&p, element, QRectF(0, 0, w, h));
p.translate(-x,-y);
renderer->render(&p, element, QRectF(0, 0, elementWidth, elementHeigh));
if (size)
*size = QSize(w, h);
//img.save(element+".png");
//img.save(element+parameters+".png");
return img;
} else {
//render the whole svg file