Qt-interest Archive, June 2007
[Patch] QPen Dash patterns in QSvgGenerator
Message 1 in thread
Hi all,
I very much appreciated the appearance of QSvgGenerator in Qt 4.3.0. I am a
hardcore SVG fan and immediately tried to implement this new feature in my
current project.
However, QSvgGenerator supports only solid QPen's, and outputs a plain black
line for dashed lines (with any pattern), disregarding other properties
such as colour (which work for solid lines).
Fortunately, it was not really difficult to implement support for this. I
attach a patch that solves the problem, and, yes, I got permission from my
boss to publish it. This code is in the public domain, and we will be most
happy if this feature is merged into Qt (we don't really want to maintain
our separate branch...).
The code takes care of the (few) differences in pattern handling between Qt
and SVG: in particular, Qt gives lengths relative to pen width, whereas SVG
uses absolute units; also, if the number of pattern entries is odd, Qt
writes a warning about it and assumes a zero entry at the end, whereas SVG
repeats the pattern to make it even.
The only missing SVG stroke property, after this patch, is stroke-dashoffset
(it could be easily implemented from QPen::dashOffset(), I'm simply being
lazy because I do not need it).
Enjoy,
-Federico Zenith
Petrell AS
Trondheim
diff -Pur qt-x11-opensource-src-4.3.0-unpatched/src/svg/qsvggenerator.cpp qt-x11-opensource-src-4.3.0/src/svg/qsvggenerator.cpp
diff -Pur qt-x11-opensource-src-4.3.0-unpatched/src/svg/qsvggenerator.cpp qt-x11-opensource-src-4.3.0/src/svg/qsvggenerator.cpp
--- qt-x11-opensource-src-4.3.0-unpatched/src/svg/qsvggenerator.cpp 2007-06-14 10:13:16.000000000 +0200
+++ qt-x11-opensource-src-4.3.0/src/svg/qsvggenerator.cpp 2007-06-14 10:09:26.000000000 +0200
@@ -49,6 +49,26 @@
*opacity_string = QString::number(color.alphaF());
}
+static void translate_dashPattern(QVector<qreal> pattern, const qreal& width, QString *pattern_string)
+{
+ Q_ASSERT(pattern_string);
+
+ // The behaviour of Qt's QPen and SVG implementations differ when given an odd number of entries.
+ // SVG assumes a null final space and issues a warning, SVG repeats the pattern twice.
+ // Here we set any missing final space to zero, so the SVG will look as the Qt's QPen.
+ // see also: http://www.w3.org/TR/SVG/painting.html#StrokeProperties
+ if(pattern.count()%2 != 0)
+ pattern.append(0);
+
+ // Note that SVG operates in absolute lengths, whereas Qt uses a length/width ratio.
+ foreach( qreal entry, pattern ) {
+ *pattern_string +=
+ QString::fromLatin1("%1,")
+ .arg(entry*width);
+ }
+ pattern_string->chop(1);
+}
+
class QSvgPaintEnginePrivate : public QPaintEnginePrivate
{
public:
@@ -101,6 +121,7 @@
QString font_family;
QString font_style;
QString stroke, strokeOpacity;
+ QString dashPattern;
QString fill, fillOpacity;
} attributes;
};
@@ -258,7 +279,22 @@
case Qt::DotLine:
case Qt::DashDotLine:
case Qt::DashDotDotLine:
- case Qt::CustomDashLine:
+ case Qt::CustomDashLine: {
+ QString color, colorOpacity, dashPattern;
+
+ translate_color(spen.color(), &color,
+ &colorOpacity);
+ translate_dashPattern(spen.dashPattern(), spen.widthF(),
+ &dashPattern);
+ d_func()->attributes.stroke = color;
+ d_func()->attributes.strokeOpacity = colorOpacity;
+ d_func()->attributes.dashPattern = dashPattern;
+
+ stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
+ stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
+ stream() << QLatin1String("stroke-dasharray=\"")<<dashPattern<< QLatin1String("\" ");
+ }
+ break;
default:
qWarning("Unsupported pen style");
break;