summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuneel BS <suneel.b-s@nokia.com>2009-05-08 07:02:52 (GMT)
committerKim Motoyoshi Kalland <kim.kalland@nokia.com>2009-06-22 13:26:15 (GMT)
commit6e057c7fce3718bcefc8ccae645aa3c377c7c587 (patch)
tree2bd717568ed35d19dc8459a34e13c923b9c86950
parent2dcb97ff789dd7a9b7534348ca49c96c09783055 (diff)
downloadQt-6e057c7fce3718bcefc8ccae645aa3c377c7c587.zip
Qt-6e057c7fce3718bcefc8ccae645aa3c377c7c587.tar.gz
Qt-6e057c7fce3718bcefc8ccae645aa3c377c7c587.tar.bz2
Clamped opacity to the range [0, 1] in the SVG module.
Modified and autotest added by Kim. Reviewed-by: Kim
-rw-r--r--src/svg/qsvghandler.cpp14
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp74
2 files changed, 81 insertions, 7 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index e2c1312..8185fc6 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -497,10 +497,8 @@ static bool constructColor(const QString &colorStr, const QString &opacity,
if (!resolveColor(colorStr, color, handler))
return false;
if (!opacity.isEmpty()) {
- qreal op = toDouble(opacity);
- if (op <= 1)
- op *= 255;
- color.setAlpha(int(op));
+ qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)));
+ color.setAlphaF(op);
}
return true;
}
@@ -644,8 +642,10 @@ static void parseBrush(QSvgNode *node,
QSvgStyleProperty *style = styleFromUrl(node, value);
if (style) {
QSvgFillStyle *prop = new QSvgFillStyle(style);
- if (!opacity.isEmpty())
- prop->setFillOpacity(toDouble(opacity));
+ if (!opacity.isEmpty()) {
+ qreal clampedOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)));
+ prop->setFillOpacity(clampedOpacity);
+ }
node->appendStyleProperty(prop, myId);
} else {
qWarning("Couldn't resolve property: %s", qPrintable(idFromUrl(value)));
@@ -1943,7 +1943,7 @@ static void parseOpacity(QSvgNode *node,
qreal op = value.toDouble(&ok);
if (ok) {
- QSvgOpacityStyle *opacity = new QSvgOpacityStyle(op);
+ QSvgOpacityStyle *opacity = new QSvgOpacityStyle(qMin(qreal(1.0), qMax(qreal(0.0), op)));
node->appendStyleProperty(opacity, someId(attributes));
}
}
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index b148f8c..d1c11ed 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -76,6 +76,7 @@ private slots:
void matrixForElement() const;
void gradientStops() const;
void fillRule();
+ void opacity();
#ifndef QT_NO_COMPRESS
void testGzLoading();
@@ -715,5 +716,78 @@ void tst_QSvgRenderer::fillRule()
}
}
+static void opacity_drawSvgAndVerify(const QByteArray &data)
+{
+ QSvgRenderer renderer(data);
+ QVERIFY(renderer.isValid());
+ QImage image(10, 10, QImage::Format_ARGB32_Premultiplied);
+ image.fill(0xffff00ff);
+ QPainter painter(&image);
+ renderer.render(&painter);
+ painter.end();
+ QCOMPARE(image.pixel(5, 5), 0xff7f7f7f);
+}
+
+void tst_QSvgRenderer::opacity()
+{
+ static const char *opacities[] = {"-1,4641", "0", "0.5", "1", "1.337"};
+ static const char *firstColors[] = {"#7f7f7f", "#7f7f7f", "#402051", "blue", "#123456"};
+ static const char *secondColors[] = {"red", "#bad", "#bedead", "#7f7f7f", "#7f7f7f"};
+
+ // Fill-opacity
+ for (int i = 0; i < 5; ++i) {
+ QByteArray data("<svg><rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"");
+ data.append(firstColors[i]);
+ data.append("\"/><rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"");
+ data.append(secondColors[i]);
+ data.append("\" fill-opacity=\"");
+ data.append(opacities[i]);
+ data.append("\"/></svg>");
+ opacity_drawSvgAndVerify(data);
+ }
+ // Stroke-opacity
+ for (int i = 0; i < 5; ++i) {
+ QByteArray data("<svg viewBox=\"0 0 10 10\"><polyline points=\"0 5 10 5\" fill=\"none\" stroke=\"");
+ data.append(firstColors[i]);
+ data.append("\" stroke-width=\"10\"/><line x1=\"5\" y1=\"0\" x2=\"5\" y2=\"10\" fill=\"none\" stroke=\"");
+ data.append(secondColors[i]);
+ data.append("\" stroke-width=\"10\" stroke-opacity=\"");
+ data.append(opacities[i]);
+ data.append("\"/></svg>");
+ opacity_drawSvgAndVerify(data);
+ }
+ // As gradients:
+ // Fill-opacity
+ for (int i = 0; i < 5; ++i) {
+ QByteArray data("<svg><defs><linearGradient id=\"gradient\"><stop offset=\"0\" stop-color=\"");
+ data.append(secondColors[i]);
+ data.append("\"/><stop offset=\"1\" stop-color=\"");
+ data.append(secondColors[i]);
+ data.append("\"/></linearGradient></defs><rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"");
+ data.append(firstColors[i]);
+ data.append("\"/><rect x=\"0\" y=\"0\" height=\"10\" width=\"10\" fill=\"url(#gradient)\" fill-opacity=\"");
+ data.append(opacities[i]);
+ data.append("\"/></svg>");
+ opacity_drawSvgAndVerify(data);
+ }
+ // When support for gradients on strokes has been implemented, add the code below.
+ /*
+ // Stroke-opacity
+ for (int i = 0; i < 5; ++i) {
+ QByteArray data("<svg viewBox=\"0 0 10 10\"><defs><linearGradient id=\"grad\"><stop offset=\"0\" stop-color=\"");
+ data.append(secondColors[i]);
+ data.append("\"/><stop offset=\"1\" stop-color=\"");
+ data.append(secondColors[i]);
+ data.append("\"/></linearGradient></defs><polyline points=\"0 5 10 5\" fill=\"none\" stroke=\"");
+ data.append(firstColors[i]);
+ data.append("\" stroke-width=\"10\" /><line x1=\"5\" y1=\"0\" x2=\"5\" y2=\"10\" fill=\"none\" stroke=\"url(#grad)\" stroke-width=\"10\" stroke-opacity=\"");
+ data.append(opacities[i]);
+ data.append("\" /></svg>");
+ opacity_drawSvgAndVerify(data);
+ }
+ */
+}
+
+
QTEST_MAIN(tst_QSvgRenderer)
#include "tst_qsvgrenderer.moc"