summaryrefslogtreecommitdiffstats
path: root/src/svg
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-07-24 09:45:33 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-07-27 13:04:30 (GMT)
commit3643028959f0b38350e57e60ba4000435b75e592 (patch)
treec129e4dee11487abd437ab8ebd993ba261e06fa6 /src/svg
parentcf66c667a97c0079141eb3f2d9e997b7378ae792 (diff)
parentc36139c665e61866aff4bf8572890a735167a7d0 (diff)
downloadQt-3643028959f0b38350e57e60ba4000435b75e592.zip
Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.gz
Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.bz2
Merge commit 'qt/master-stable'
Conflicts: configure.exe qmake/Makefile.unix qmake/generators/makefile.cpp src/corelib/global/qglobal.h src/corelib/kernel/kernel.pri src/corelib/kernel/qcoreevent.cpp src/corelib/kernel/qsharedmemory_unix.cpp src/gui/graphicsview/qgraphicsscene.cpp src/gui/kernel/qaction.cpp src/gui/kernel/qaction.h src/gui/kernel/qaction_p.h src/gui/kernel/qapplication.cpp src/gui/kernel/qapplication.h src/gui/kernel/qwidget.cpp src/gui/kernel/qwidget.h src/gui/kernel/qwidget_mac.mm src/gui/painting/qgraphicssystemfactory.cpp src/gui/styles/qwindowsstyle.cpp src/gui/text/qfontengine_qpf.cpp src/gui/widgets/qabstractscrollarea_p.h src/network/access/qnetworkaccessdebugpipebackend.cpp src/network/socket/qlocalsocket_unix.cpp src/network/socket/qnativesocketengine_p.h src/network/socket/qnativesocketengine_unix.cpp src/openvg/qpaintengine_vg.cpp tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp tests/auto/qcssparser/qcssparser.pro tests/auto/qdir/tst_qdir.cpp tests/auto/qfile/tst_qfile.cpp tests/auto/qobject/tst_qobject.cpp tests/auto/qpathclipper/qpathclipper.pro tests/auto/qprocess/tst_qprocess.cpp tests/auto/qsettings/tst_qsettings.cpp tests/auto/qsharedpointer/qsharedpointer.pro tests/auto/qsqlquerymodel/qsqlquerymodel.pro tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro tests/auto/qsqltablemodel/qsqltablemodel.pro tests/auto/qsqlthread/qsqlthread.pro tests/auto/qwidget/tst_qwidget.cpp
Diffstat (limited to 'src/svg')
-rw-r--r--src/svg/qsvghandler.cpp336
-rw-r--r--src/svg/qsvgnode.cpp2
-rw-r--r--src/svg/qsvgstyle.cpp56
-rw-r--r--src/svg/qsvgstyle_p.h41
4 files changed, 283 insertions, 152 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 345dcf3..5857e1c 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -68,6 +68,7 @@
QT_BEGIN_NAMESPACE
+
double qstrtod(const char *s00, char const **se, bool *ok);
static bool parsePathDataFast(const QStringRef &data, QPainterPath &path);
@@ -320,6 +321,7 @@ static qreal toDouble(const QChar *&str)
++str;
}
}
+
temp[pos] = '\0';
qreal val;
@@ -365,16 +367,24 @@ static qreal toDouble(const QChar *&str)
return val;
}
-static qreal toDouble(const QString &str)
+static qreal toDouble(const QString &str, bool *ok = NULL)
{
const QChar *c = str.constData();
- return toDouble(c);
+ qreal res = toDouble(c);
+ if (ok) {
+ *ok = ((*c) == QLatin1Char('\0'));
+ }
+ return res;
}
-static qreal toDouble(const QStringRef &str)
+static qreal toDouble(const QStringRef &str, bool *ok = NULL)
{
const QChar *c = str.constData();
- return toDouble(c);
+ qreal res = toDouble(c);
+ if (ok) {
+ *ok = (c == (str.constData() + str.length()));
+ }
+ return res;
}
static QVector<qreal> parseNumbersList(const QChar *&str)
@@ -497,14 +507,17 @@ static bool constructColor(const QString &colorStr, const QString &opacity,
if (!resolveColor(colorStr, color, handler))
return false;
if (!opacity.isEmpty()) {
- qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)));
+ bool ok = true;
+ qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity, &ok)));
+ if (!ok)
+ op = 1.0;
color.setAlphaF(op);
}
return true;
}
static qreal parseLength(const QString &str, QSvgHandler::LengthType &type,
- QSvgHandler *handler)
+ QSvgHandler *handler, bool *ok = NULL)
{
QString numStr = str.trimmed();
@@ -533,15 +546,15 @@ static qreal parseLength(const QString &str, QSvgHandler::LengthType &type,
type = handler->defaultCoordinateSystem();
//type = QSvgHandler::LT_OTHER;
}
- qreal len = toDouble(numStr);
+ qreal len = toDouble(numStr, ok);
//qDebug()<<"len is "<<len<<", from '"<<numStr << "'";
return len;
}
-static inline qreal convertToNumber(const QString &str, QSvgHandler *handler)
+static inline qreal convertToNumber(const QString &str, QSvgHandler *handler, bool *ok = NULL)
{
QSvgHandler::LengthType type;
- qreal num = parseLength(str, type, handler);
+ qreal num = parseLength(str, type, handler, ok);
if (type == QSvgHandler::LT_PERCENT) {
num = num/100.0;
}
@@ -631,15 +644,25 @@ static void parseBrush(QSvgNode *node,
QString opacity = attributes.value(QLatin1String("fill-opacity")).toString();
QString myId = someId(attributes);
- value = value.trimmed();
- fillRule = fillRule.trimmed();
- if (!value.isEmpty() || !fillRule.isEmpty()) {
- Qt::FillRule f = Qt::WindingFill;
+ QSvgFillStyle *prop = new QSvgFillStyle(0);
+
+ //fill-rule attribute handling
+ if (!fillRule.isEmpty() && fillRule != QLatin1String("inherit")) {
if (fillRule == QLatin1String("evenodd"))
- f = Qt::OddEvenFill;
+ prop->setFillRule(Qt::OddEvenFill);
+ else if (fillRule == QLatin1String("nonzero"))
+ prop->setFillRule(Qt::WindingFill);
+ }
+
+ //fill-opacity atttribute handling
+ if (!opacity.isEmpty() && opacity != QLatin1String("inherit")) {
+ prop->setFillOpacity(qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))));
+ }
+
+ //fill attribute handling
+ if ((!value.isEmpty()) && (value != QLatin1String("inherit")) ) {
if (value.startsWith(QLatin1String("url"))) {
value = value.remove(0, 3);
- QSvgFillStyle *prop = new QSvgFillStyle(0);
QSvgStyleProperty *style = styleFromUrl(node, value);
if (style) {
prop->setFillStyle(style);
@@ -648,30 +671,18 @@ static void parseBrush(QSvgNode *node,
prop->setGradientId(id);
prop->setGradientResolved(false);
}
- if (!opacity.isEmpty()) {
- qreal clampedOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)));
- prop->setFillOpacity(clampedOpacity);
- }
- if (!fillRule.isEmpty())
- prop->setFillRule(f);
- node->appendStyleProperty(prop,myId);
} else if (value != QLatin1String("none")) {
QColor color;
- if (constructColor(value, opacity, color, handler)) {
- QSvgFillStyle *prop = new QSvgFillStyle(QBrush(color));
- if (!fillRule.isEmpty())
- prop->setFillRule(f);
- node->appendStyleProperty(prop, myId);
- }
+ if (resolveColor(value, color, handler))
+ prop->setBrush(QBrush(color));
} else {
- QSvgFillStyle *prop = new QSvgFillStyle(QBrush(Qt::NoBrush));
- if (!fillRule.isEmpty())
- prop->setFillRule(f);
- node->appendStyleProperty(prop, myId);
+ prop->setBrush(QBrush(Qt::NoBrush));
}
}
+ node->appendStyleProperty(prop,myId);
}
+
static void parseQPen(QPen &pen, QSvgNode *node,
const QSvgAttributes &attributes,
QSvgHandler *handler)
@@ -908,103 +919,155 @@ static void parsePen(QSvgNode *node,
//qDebug()<<"Node "<<node->type()<<", attrs are "<<value<<width;
- if (!value.isEmpty() || !width.isEmpty() || !linecap.isEmpty() || !linejoin.isEmpty()) {
- if (value != QLatin1String("none")) {
- QSvgStrokeStyle *inherited =
- static_cast<QSvgStrokeStyle*>(node->styleProperty(
- QSvgStyleProperty::STROKE));
- if (!inherited)
- inherited = static_cast<QSvgStrokeStyle*>(node->parent()->styleProperty(
- QSvgStyleProperty::STROKE));
- QPen pen(handler->defaultPen());
- if (inherited)
- pen = inherited->qpen();
+ /* All the below checks needed because g (or any container element) can have only one of these attributes.
+ * If it doesn't has any one of these, then processing below not needed */
+
+ if (!value.isEmpty() || !width.isEmpty() || !dashArray.isEmpty() || !linecap.isEmpty() ||
+ !linejoin.isEmpty() || !miterlimit.isEmpty() || !opacity.isEmpty() || !dashOffset.isEmpty() ) {
+ //if (value != QLatin1String("none")) {
+ /* If stroke = "none" then also, we need to parse below, because elements like 'g' may
+ have other defined stroke attributes, which will be inherited by its children */
+ QSvgStrokeStyle *inherited =
+ static_cast<QSvgStrokeStyle*>(node->parent()->styleProperty(
+ QSvgStyleProperty::STROKE));
+
+ QPen pen(handler->defaultPen());
+ bool stroke = false;
+ if (inherited) {
+ pen = inherited->qpen();
+ stroke = inherited->strokePresent();
+ }
- if (!value.isEmpty()) {
- if (value.startsWith(QLatin1String("url"))) {
- value = value.remove(0, 3);
- QSvgStyleProperty *style = styleFromUrl(node, value);
- if (style) {
- if (style->type() == QSvgStyleProperty::GRADIENT) {
- QBrush b(*((QSvgGradientStyle*)style)->qgradient());
- pen.setBrush(b);
- } else if (style->type() == QSvgStyleProperty::SOLID_COLOR) {
- pen.setColor(
- ((QSvgSolidColorStyle*)style)->qcolor());
- }
- } else {
- qWarning() << "QSvgHandler::parsePen could not resolve property" << idFromUrl(value);
+ // stroke-opacity attribute handling
+ qreal strokeAlpha;
+ if (!opacity.isEmpty() && opacity != QLatin1String("inherit")) {
+ strokeAlpha = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)));
+ } else {
+ strokeAlpha = pen.color().alphaF();
+ }
+
+ //stroke attribute handling
+ if (!value.isEmpty() && value != QLatin1String("inherit")) {
+ if (value.startsWith(QLatin1String("url"))) {
+ value = value.remove(0, 3);
+ QSvgStyleProperty *style = styleFromUrl(node, value);
+ if (style) {
+ if (style->type() == QSvgStyleProperty::GRADIENT) {
+ QBrush b(*((QSvgGradientStyle*)style)->qgradient());
+ pen.setBrush(b);
+ } else if (style->type() == QSvgStyleProperty::SOLID_COLOR) {
+ pen.setColor(
+ ((QSvgSolidColorStyle*)style)->qcolor());
}
+ pen.setStyle(Qt::SolidLine);
+ stroke = true;
} else {
- QColor color;
- if (constructColor(value, opacity, color, handler))
- pen.setColor(color);
+ qWarning() << "QSvgHandler::parsePen could not resolve property" << idFromUrl(value);
}
- //since we could inherit stroke="none"
- //we need to reset the style of our stroke to something
- pen.setStyle(Qt::SolidLine);
- }
- if (!width.isEmpty()) {
- QSvgHandler::LengthType lt;
- qreal widthF = parseLength(width, lt, handler);
- //### fixme
- if (!widthF) {
- pen.setStyle(Qt::NoPen);
- return;
+ } else if (value == QLatin1String("none")) {
+ QColor color; //### fixme: dafalut value for color.
+ color.setAlphaF(strokeAlpha);
+ pen.setColor(color);
+ stroke = false; // This is required because, parent may have a valid stroke but the child may have stroke = "none"
+ } else {
+ QColor color;
+ if (resolveColor(value, color, handler)) {
+ color.setAlphaF(strokeAlpha);
+ pen.setColor(color);
}
- pen.setWidthF(widthF);
- }
-
- if (!linejoin.isEmpty()) {
- if (linejoin == QLatin1String("miter"))
- pen.setJoinStyle(Qt::SvgMiterJoin);
- else if (linejoin == QLatin1String("round"))
- pen.setJoinStyle(Qt::RoundJoin);
- else if (linejoin == QLatin1String("bevel"))
- pen.setJoinStyle(Qt::BevelJoin);
+ stroke = true;
}
+ } else {
+ QColor color = pen.color();
+ color.setAlphaF(strokeAlpha);
+ pen.setColor(color);
+ }
- if (!linecap.isEmpty()) {
- if (linecap == QLatin1String("butt"))
- pen.setCapStyle(Qt::FlatCap);
- else if (linecap == QLatin1String("round"))
- pen.setCapStyle(Qt::RoundCap);
- else if (linecap == QLatin1String("square"))
- pen.setCapStyle(Qt::SquareCap);
- }
+ //stroke-width handling
+ if (!width.isEmpty() && width != QLatin1String("inherit")) {
+ qreal widthF;
+ QSvgHandler::LengthType lt;
+ widthF = parseLength(width, lt, handler);
+ pen.setWidthF(widthF);
+ } else if (inherited){
+ qreal widthF = inherited->qpen().widthF();
+ pen.setWidthF(widthF);
+ }
- qreal penw = pen.widthF();
- if (!dashArray.isEmpty()) {
- const QChar *s = dashArray.constData();
- QVector<qreal> dashes = parseNumbersList(s);
- qreal *d = dashes.data();
- if(penw != 0)
- for (int i = 0; i < dashes.size(); ++i) {
- *d /= penw;
- ++d;
- }
+ //stroke-linejoin attribute handling
+ if (!linejoin.isEmpty()) {
+ if (linejoin == QLatin1String("miter"))
+ pen.setJoinStyle(Qt::SvgMiterJoin);
+ else if (linejoin == QLatin1String("round"))
+ pen.setJoinStyle(Qt::RoundJoin);
+ else if (linejoin == QLatin1String("bevel"))
+ pen.setJoinStyle(Qt::BevelJoin);
+ }
- // if the dash count is odd the dashes should be duplicated
- if (dashes.size() % 2 != 0)
- dashes << QVector<qreal>(dashes);
+ //stroke-linecap attribute handling
+ if (!linecap.isEmpty()) {
+ if (linecap == QLatin1String("butt"))
+ pen.setCapStyle(Qt::FlatCap);
+ else if (linecap == QLatin1String("round"))
+ pen.setCapStyle(Qt::RoundCap);
+ else if (linecap == QLatin1String("square"))
+ pen.setCapStyle(Qt::SquareCap);
+ }
- pen.setDashPattern(dashes);
- }
- if (!dashOffset.isEmpty()) {
- qreal doffset = toDouble(dashOffset);
- if (penw != 0)
- doffset /= penw;
- pen.setDashOffset(doffset);
+ //strok-dasharray attribute handling
+ qreal penw = pen.widthF();
+ if (!dashArray.isEmpty() && dashArray != QLatin1String("inherit")) {
+ const QChar *s = dashArray.constData();
+ QVector<qreal> dashes = parseNumbersList(s);
+ qreal *d = dashes.data();
+ if (penw != 0)
+ for (int i = 0; i < dashes.size(); ++i) {
+ *d /= penw;
+ ++d;
+ }
+ // if the dash count is odd the dashes should be duplicated
+ if (dashes.size() % 2 != 0)
+ dashes << QVector<qreal>(dashes);
+ pen.setDashPattern(dashes);
+ } else if (inherited) {
+ QVector<qreal> dashes(inherited->qpen().dashPattern());
+ qreal *d = dashes.data();
+ if (!penw)
+ penw = 1.0;
+ qreal inheritpenw = inherited->qpen().widthF();
+ if (!inheritpenw)
+ inheritpenw = 1.0;
+ for ( int i = 0; i < dashes.size(); ++i) {
+ *d *= (inheritpenw/ penw);
+ ++d;
}
- if (!miterlimit.isEmpty())
- pen.setMiterLimit(toDouble(miterlimit));
+ pen.setDashPattern(dashes);
+ }
- node->appendStyleProperty(new QSvgStrokeStyle(pen), myId);
- } else {
- QPen pen(handler->defaultPen());
- pen.setStyle(Qt::NoPen);
- node->appendStyleProperty(new QSvgStrokeStyle(pen), myId);
+
+ //stroke-dashoffset attribute handling
+ if (!dashOffset.isEmpty() && dashOffset != QLatin1String("inherit")) {
+ qreal doffset = toDouble(dashOffset);
+ if (penw != 0)
+ doffset /= penw;
+ pen.setDashOffset(doffset);
+ } else if (inherited) {
+ qreal doffset = pen.dashOffset();
+ if (!penw)
+ penw = 1.0;
+ qreal inheritpenw = inherited->qpen().widthF();
+ if (!inheritpenw)
+ inheritpenw = 1.0;
+ doffset *= (inheritpenw/ penw);
+ pen.setDashOffset(doffset);
}
+
+ if (!miterlimit.isEmpty() && miterlimit != QLatin1String("inherit"))
+ pen.setMiterLimit(toDouble(miterlimit));
+
+ QSvgStrokeStyle *prop = new QSvgStrokeStyle(pen);
+ prop->setStroke(stroke);
+ node->appendStyleProperty(prop, myId);
}
}
@@ -1071,10 +1134,14 @@ static bool parseQFont(const QSvgAttributes &attributes,
font.setFamily(family.trimmed());
}
if (!size.isEmpty()) {
- QSvgHandler::LengthType dummy; // should always be pixel size
- fontSize = parseLength(size, dummy, handler);
- if (fontSize <= 0)
- fontSize = 1;
+ if (size == QLatin1String("inherit")) {
+ //inherited already
+ } else {
+ QSvgHandler::LengthType dummy; // should always be pixel size
+ fontSize = parseLength(size, dummy, handler);
+ if (fontSize <= 0)
+ fontSize = 1;
+ }
font.setPixelSize(qMax(1, int(fontSize)));
}
if (!style.isEmpty()) {
@@ -1154,9 +1221,13 @@ static void parseFont(QSvgNode *node,
font = inherited->qfont();
fontSize = inherited->pointSize();
}
- if (parseQFont(attributes, font, fontSize, handler)) {
+ // group or any container element can have only text-anchor and should
+ // be processed, because its children can inherit from it.
+ // So checking for text-anchor before parseQfont()
+ QString anchor = attributes.value(QLatin1String("text-anchor")).toString();
+ if (parseQFont(attributes, font, fontSize, handler) || (!anchor.isEmpty())) {
QString myId = someId(attributes);
- QString anchor = attributes.value(QLatin1String("text-anchor")).toString();
+ //QString anchor = attributes.value(QLatin1String("text-anchor")).toString();
QSvgTinyDocument *doc = node->document();
QSvgFontStyle *fontStyle = 0;
QString family = (font.family().isEmpty())?myId:font.family();
@@ -1865,7 +1936,7 @@ static bool parseDefaultTextStyle(QSvgNode *node,
if (fontStyle) {
font = fontStyle->qfont();
fontSize = fontStyle->pointSize();
- if (anchor.isEmpty())
+ if (anchor.isEmpty() || anchor == QLatin1String("inherit"))
anchor = fontStyle->textAnchor();
}
@@ -2946,7 +3017,11 @@ static bool parseStopNode(QSvgStyleProperty *parent,
QString colorStr = attrs.value(QString(), QLatin1String("stop-color")).toString();
QString opacityStr = attrs.value(QString(), QLatin1String("stop-opacity")).toString();
QColor color;
- qreal offset = convertToNumber(offsetStr, handler);
+
+ bool ok = true;
+ qreal offset = convertToNumber(offsetStr, handler, &ok);
+ if (!ok)
+ offset = 0.0;
if (colorStr.isEmpty()) {
colorStr = QLatin1String("#000000");
}
@@ -3035,12 +3110,16 @@ static QSvgNode *createSvgNode(QSvgNode *parent,
QStringList lst = viewBoxStr.split(QLatin1Char(' '), QString::SkipEmptyParts);
if (lst.count() != 4)
lst = viewBoxStr.split(QLatin1Char(','), QString::SkipEmptyParts);
+ int count = lst.count();
+ while (count < 4) {
+ lst.append(QLatin1String(""));
+ count++;
+ }
QString xStr = lst.at(0).trimmed();
QString yStr = lst.at(1).trimmed();
QString widthStr = lst.at(2).trimmed();
QString heightStr = lst.at(3).trimmed();
-
QSvgHandler::LengthType lt;
qreal x = parseLength(xStr, lt, handler);
qreal y = parseLength(yStr, lt, handler);
@@ -3048,15 +3127,14 @@ static QSvgNode *createSvgNode(QSvgNode *parent,
qreal h = parseLength(heightStr, lt, handler);
node->setViewBox(QRectF(x, y, w, h));
- } else if (width && height){
+
+ } else if (width && height) {
if (type == QSvgHandler::LT_PT) {
width = convertToPixels(width, false, type);
height = convertToPixels(height, false, type);
}
-
node->setViewBox(QRectF(0, 0, width, height));
}
-
handler->setDefaultCoordinateSystem(QSvgHandler::LT_PX);
return node;
@@ -3395,7 +3473,7 @@ void QSvgHandler::init()
m_style = 0;
m_animEnd = 0;
m_defaultCoords = LT_PX;
- m_defaultPen = QPen(Qt::black, 1, Qt::NoPen, Qt::FlatCap, Qt::SvgMiterJoin);
+ m_defaultPen = QPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::SvgMiterJoin);
m_defaultPen.setMiterLimit(4);
parse();
}
diff --git a/src/svg/qsvgnode.cpp b/src/svg/qsvgnode.cpp
index 75c01a9..ce8b3fa 100644
--- a/src/svg/qsvgnode.cpp
+++ b/src/svg/qsvgnode.cpp
@@ -320,7 +320,7 @@ qreal QSvgNode::strokeWidth() const
{
QSvgStrokeStyle *stroke = static_cast<QSvgStrokeStyle*>(
styleProperty(QSvgStyleProperty::STROKE));
- if (!stroke || stroke->qpen().style() == Qt::NoPen)
+ if (!stroke || !stroke->strokePresent())
return 0;
return stroke->qpen().widthF();
}
diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp
index fec6231..c3c0a68 100644
--- a/src/svg/qsvgstyle.cpp
+++ b/src/svg/qsvgstyle.cpp
@@ -81,12 +81,25 @@ void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &)
}
QSvgFillStyle::QSvgFillStyle(const QBrush &brush)
- : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true)
+ : m_fill(brush)
+ , m_style(0)
+ , m_fillRuleSet(false)
+ , m_fillRule(Qt::WindingFill)
+ , m_fillOpacitySet(false)
+ , m_fillOpacity(1.0)
+ , m_gradientResolved(true)
+ , m_fillSet(true)
{
}
QSvgFillStyle::QSvgFillStyle(QSvgStyleProperty *style)
- : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true)
+ : m_style(style)
+ , m_fillRuleSet(false)
+ , m_fillRule(Qt::WindingFill)
+ , m_fillOpacitySet(false)
+ , m_fillOpacity(1.0)
+ , m_gradientResolved(true)
+ , m_fillSet(style != 0)
{
}
@@ -102,6 +115,19 @@ void QSvgFillStyle::setFillOpacity(qreal opacity)
m_fillOpacity = opacity;
}
+void QSvgFillStyle::setFillStyle(QSvgStyleProperty* style)
+{
+ m_style = style;
+ m_fillSet = true;
+}
+
+void QSvgFillStyle::setBrush(QBrush brush)
+{
+ m_fill = brush;
+ m_style = 0;
+ m_fillSet = true;
+}
+
static void recursivelySetFill(QSvgNode *node, Qt::FillRule f)
{
if (node->type() == QSvgNode::PATH) {
@@ -126,20 +152,26 @@ void QSvgFillStyle::apply(QPainter *p, const QRectF &rect, QSvgNode *node, QSvgE
recursivelySetFill(node, m_fillRule);
m_fillRuleSet = false;//set it only on the first run
}
- p->setBrush(m_fill);
+ if (m_fillSet) {
+ if (m_style)
+ m_style->apply(p, rect, node, states);
+ else
+ p->setBrush(m_fill);
+ }
if (m_fillOpacitySet)
states.fillOpacity = m_fillOpacity;
- if (m_style)
- m_style->apply(p, rect, node, states);
}
void QSvgFillStyle::revert(QPainter *p, QSvgExtraStates &states)
{
- if (m_style)
- m_style->revert(p, states);
- p->setBrush(m_oldFill);
if (m_fillOpacitySet)
states.fillOpacity = m_oldOpacity;
+ if (m_fillSet) {
+ if (m_style)
+ m_style->revert(p, states);
+ else
+ p->setBrush(m_oldFill);
+ }
}
QSvgViewportFillStyle::QSvgViewportFillStyle(const QBrush &brush)
@@ -195,14 +227,18 @@ void QSvgFontStyle::revert(QPainter *p, QSvgExtraStates &)
}
QSvgStrokeStyle::QSvgStrokeStyle(const QPen &pen)
- : m_stroke(pen)
+ : m_stroke(pen), m_strokePresent(true)
{
}
void QSvgStrokeStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &)
{
m_oldStroke = p->pen();
- p->setPen(m_stroke);
+ if (!m_strokePresent || !m_stroke.widthF() || !m_stroke.color().alphaF()) {
+ p->setPen(Qt::NoPen);
+ } else {
+ p->setPen(m_stroke);
+ }
}
void QSvgStrokeStyle::revert(QPainter *p, QSvgExtraStates &)
diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h
index e65b6f5..70ecf5b 100644
--- a/src/svg/qsvgstyle_p.h
+++ b/src/svg/qsvgstyle_p.h
@@ -224,12 +224,29 @@ public:
void setFillRule(Qt::FillRule f);
void setFillOpacity(qreal opacity);
+ void setFillStyle(QSvgStyleProperty* style);
+ void setBrush(QBrush brush);
const QBrush & qbrush() const
{
return m_fill;
}
+ qreal fillOpacity() const
+ {
+ return m_fillOpacity;
+ }
+
+ Qt::FillRule fillRule() const
+ {
+ return m_fillRule;
+ }
+
+ QSvgStyleProperty* style() const
+ {
+ return m_style;
+ }
+
void setGradientId(const QString &Id)
{
m_gradientId = Id;
@@ -240,7 +257,6 @@ public:
return m_gradientId;
}
-
void setGradientResolved(bool resolved)
{
m_gradientResolved = resolved;
@@ -251,16 +267,6 @@ public:
return m_gradientResolved;
}
- void setFillStyle(QSvgStyleProperty* style)
- {
- m_style = style;
- }
-
- void setBrush(QBrush brush)
- {
- m_fill = brush;
- }
-
private:
// fill v v 'inherit' | <Paint.datatype>
// fill-opacity v v 'inherit' | <OpacityValue.datatype>
@@ -275,6 +281,7 @@ private:
qreal m_oldOpacity;
QString m_gradientId;
bool m_gradientResolved;
+ bool m_fillSet;
};
class QSvgViewportFillStyle : public QSvgStyleProperty
@@ -345,6 +352,16 @@ public:
virtual void revert(QPainter *p, QSvgExtraStates &states);
virtual Type type() const;
+ void setStroke(bool stroke)
+ {
+ m_strokePresent = stroke;
+ }
+
+ bool strokePresent() const
+ {
+ return m_strokePresent;
+ }
+
const QPen & qpen() const
{
return m_stroke;
@@ -359,8 +376,8 @@ private:
// stroke-opacity v v 'inherit' | <OpacityValue.datatype>
// stroke-width v v 'inherit' | <StrokeWidthValue.datatype>
QPen m_stroke;
-
QPen m_oldStroke;
+ bool m_strokePresent;
};