From 2dcb97ff789dd7a9b7534348ca49c96c09783055 Mon Sep 17 00:00:00 2001 From: Suneel BS Date: Fri, 8 May 2009 14:47:36 +0530 Subject: Fixed fill-rule for polygon SVG element. Polygon element should apply the fill rule which is specified in its fill-rule attribute. Default fill rule is 'WindingFill' (nonzero). Modified and autotest added by Kim. Reviewed-by: Kim --- src/svg/qsvggraphics.cpp | 5 +- src/svg/qsvggraphics_p.h | 5 ++ src/svg/qsvgstyle.cpp | 3 ++ tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 72 ++++++++++++++++++++++------ 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/src/svg/qsvggraphics.cpp b/src/svg/qsvggraphics.cpp index 6782429..e09f382 100644 --- a/src/svg/qsvggraphics.cpp +++ b/src/svg/qsvggraphics.cpp @@ -198,9 +198,8 @@ QRectF QSvgPath::bounds() const } QSvgPolygon::QSvgPolygon(QSvgNode *parent, const QPolygonF &poly) - : QSvgNode(parent), m_poly(poly) + : QSvgNode(parent), m_poly(poly), m_fillRule(Qt::WindingFill) { - } QRectF QSvgPolygon::bounds() const @@ -217,7 +216,7 @@ QRectF QSvgPolygon::bounds() const void QSvgPolygon::draw(QPainter *p, QSvgExtraStates &states) { - QT_SVG_DRAW_SHAPE(p->drawPolygon(m_poly)); + QT_SVG_DRAW_SHAPE(p->drawPolygon(m_poly, m_fillRule)); } diff --git a/src/svg/qsvggraphics_p.h b/src/svg/qsvggraphics_p.h index 8a412c4..4a19c7e 100644 --- a/src/svg/qsvggraphics_p.h +++ b/src/svg/qsvggraphics_p.h @@ -155,8 +155,13 @@ public: virtual void draw(QPainter *p, QSvgExtraStates &states); virtual Type type() const; virtual QRectF bounds() const; + void setFillRule(Qt::FillRule f) + { + m_fillRule = f; + } private: QPolygonF m_poly; + Qt::FillRule m_fillRule; }; class QSvgPolyline : public QSvgNode diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index fa996f4..9d46649 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -107,6 +107,9 @@ static void recursivelySetFill(QSvgNode *node, Qt::FillRule f) if (node->type() == QSvgNode::PATH) { QSvgPath *path = static_cast(node); path->qpath()->setFillRule(f); + } else if (node->type() == QSvgNode::POLYGON) { + QSvgPolygon *polygon = static_cast(node); + polygon->setFillRule(f); } else if (node->type() == QSvgNode::G) { QList renderers = static_cast(node)->renderers(); foreach(QSvgNode *n, renderers) { diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index e8cb089..b148f8c 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -331,7 +331,7 @@ void tst_QSvgRenderer::nestedQXmlStreamReader() const QCOMPARE(reader.readNext(), QXmlStreamReader::StartDocument); QCOMPARE(reader.readNext(), QXmlStreamReader::StartElement); QCOMPARE(reader.name().toString(), QLatin1String("bar")); - + QPicture picture; QPainter painter(&picture); QSvgRenderer renderer(&reader); @@ -653,22 +653,66 @@ void tst_QSvgRenderer::testGzHelper() void tst_QSvgRenderer::fillRule() { - QByteArray data( + static const char *svgs[] = { + // Paths + // Default fill-rule (nonzero) "" - "" - "" - ""); - - QSvgRenderer renderer(data); - - QImage image(128, 128, QImage::Format_ARGB32_Premultiplied); - image.fill(0); + " " + " " + "", + // nonzero + "" + " " + " " + "", + // evenodd + "" + " " + " " + "", - QPainter painter(&image); - renderer.render(&painter); - painter.end(); + // Polygons + // Default fill-rule (nonzero) + "" + " " + " " + "", + // nonzero + "" + " " + " " + "", + // evenodd + "" + " " + " " + "" + }; - QCOMPARE(image.pixel(64, 64), QColor(Qt::red).rgba()); + const int COUNT = sizeof(svgs) / sizeof(svgs[0]); + QImage refImageNonZero(30, 30, QImage::Format_ARGB32_Premultiplied); + QImage refImageEvenOdd(30, 30, QImage::Format_ARGB32_Premultiplied); + refImageNonZero.fill(0xffff0000); + refImageEvenOdd.fill(0xffff0000); + QPainter p; + p.begin(&refImageNonZero); + p.fillRect(QRectF(0, 0, 10, 10), Qt::blue); + p.end(); + p.begin(&refImageEvenOdd); + p.fillRect(QRectF(0, 0, 10, 10), Qt::blue); + p.fillRect(QRectF(10, 10, 10, 10), Qt::blue); + p.end(); + + for (int i = 0; i < COUNT; ++i) { + QByteArray data(svgs[i]); + QSvgRenderer renderer(data); + QImage image(30, 30, QImage::Format_ARGB32_Premultiplied); + image.fill(0); + p.begin(&image); + renderer.render(&p); + p.end(); + QCOMPARE(image, i % 3 == 2 ? refImageEvenOdd : refImageNonZero); + } } QTEST_MAIN(tst_QSvgRenderer) -- cgit v0.12