void StyleLoader::loadComposite(QRadialGradient& value) { int coordinateMode; int spread; QPointF center; QPointF focal; double radius; QGradientStops stopPoints; load("coordinateMode", coordinateMode); load("spread", spread); load("centerPoint", center); load("focalPoint", focal); load("radius", radius); load("stopPoints", stopPoints); value = QRadialGradient(center, radius, focal); value.setSpread((QGradient::Spread) spread); value.setCoordinateMode((QGradient::CoordinateMode) coordinateMode); value.setStops(stopPoints); }
QBrush XMLParseBase::parseGradient(const QDomElement &element) { QBrush brush; QString gradientStart = element.attribute("start", ""); QString gradientEnd = element.attribute("end", ""); int gradientAlpha = element.attribute("alpha", "255").toInt(); QString direction = element.attribute("direction", "vertical"); QGradientStops stops; if (!gradientStart.isEmpty()) { QColor startColor = QColor(gradientStart); startColor.setAlpha(gradientAlpha); QGradientStop stop(0.0, startColor); stops.append(stop); } for (QDomNode child = element.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement childElem = child.toElement(); if (childElem.tagName() == "stop") { float position = childElem.attribute("position", "0").toFloat(); QString color = childElem.attribute("color", ""); int alpha = childElem.attribute("alpha", "-1").toInt(); if (alpha < 0) alpha = gradientAlpha; QColor stopColor = QColor(color); stopColor.setAlpha(alpha); QGradientStop stop((position / 100), stopColor); stops.append(stop); } } if (!gradientEnd.isEmpty()) { QColor endColor = QColor(gradientEnd); endColor.setAlpha(gradientAlpha); QGradientStop stop(1.0, endColor); stops.append(stop); } if (direction == "radial") { QRadialGradient gradient; gradient.setCoordinateMode(QGradient::ObjectBoundingMode); float x1 = 0.5, y1 = 0.5, radius = 0.5; gradient.setCenter(x1,y1); gradient.setFocalPoint(x1,y1); gradient.setRadius(radius); gradient.setStops(stops); brush = QBrush(gradient); } else // Linear { QLinearGradient gradient; gradient.setCoordinateMode(QGradient::ObjectBoundingMode); float x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0; if (direction == "vertical") { x1 = 0.5; x2 = 0.5; y1 = 0.0; y2 = 1.0; } else if (direction == "diagonal") { x1 = 0.0; x2 = 1.0; y1 = 0.0; y2 = 1.0; } else // Horizontal { x1 = 0.0; x2 = 1.0; y1 = 0.5; y2 = 0.5; } gradient.setStart(x1, y1); gradient.setFinalStop(x2, y2); gradient.setStops(stops); brush = QBrush(gradient); } return brush; }
bool SvgParser::parseGradient(const KoXmlElement &e, const KoXmlElement &referencedBy) { // IMPROVEMENTS: // - Store the parsed colorstops in some sort of a cache so they don't need to be parsed again. // - A gradient inherits attributes it does not have from the referencing gradient. // - Gradients with no color stops have no fill or stroke. // - Gradients with one color stop have a solid color. SvgGraphicsContext *gc = m_context.currentGC(); if (!gc) return false; SvgGradientHelper gradhelper; if (e.hasAttribute("xlink:href")) { QString href = e.attribute("xlink:href").mid(1); if (! href.isEmpty()) { // copy the referenced gradient if found SvgGradientHelper *pGrad = findGradient(href); if (pGrad) gradhelper = *pGrad; } else { //gc->fillType = SvgGraphicsContext::None; // <--- TODO Fill OR Stroke are none return false; } } // Use the gradient that is referencing, or if there isn't one, the original gradient. KoXmlElement b; if (!referencedBy.isNull()) b = referencedBy; else b = e; QString gradientId = b.attribute("id"); if (! gradientId.isEmpty()) { // check if we have this gradient already parsed // copy existing gradient if it exists if (m_gradients.find(gradientId) != m_gradients.end()) gradhelper.copyGradient(m_gradients[ gradientId ].gradient()); } if (b.attribute("gradientUnits") == "userSpaceOnUse") gradhelper.setGradientUnits(SvgGradientHelper::UserSpaceOnUse); // parse color prop QColor c = gc->currentColor; if (!b.attribute("color").isEmpty()) { m_context.styleParser().parseColor(c, b.attribute("color")); } else { // try style attr QString style = b.attribute("style").simplified(); const QStringList substyles = style.split(';', QString::SkipEmptyParts); for (QStringList::ConstIterator it = substyles.begin(); it != substyles.end(); ++it) { QStringList substyle = it->split(':'); QString command = substyle[0].trimmed(); QString params = substyle[1].trimmed(); if (command == "color") m_context.styleParser().parseColor(c, params); } } gc->currentColor = c; if (b.tagName() == "linearGradient") { QLinearGradient *g = new QLinearGradient(); if (gradhelper.gradientUnits() == SvgGradientHelper::ObjectBoundingBox) { g->setCoordinateMode(QGradient::ObjectBoundingMode); g->setStart(QPointF(SvgUtil::fromPercentage(b.attribute("x1", "0%")), SvgUtil::fromPercentage(b.attribute("y1", "0%")))); g->setFinalStop(QPointF(SvgUtil::fromPercentage(b.attribute("x2", "100%")), SvgUtil::fromPercentage(b.attribute("y2", "0%")))); } else { g->setStart(QPointF(SvgUtil::fromUserSpace(b.attribute("x1").toDouble()), SvgUtil::fromUserSpace(b.attribute("y1").toDouble()))); g->setFinalStop(QPointF(SvgUtil::fromUserSpace(b.attribute("x2").toDouble()), SvgUtil::fromUserSpace(b.attribute("y2").toDouble()))); } // preserve color stops if (gradhelper.gradient()) g->setStops(gradhelper.gradient()->stops()); gradhelper.setGradient(g); } else if (b.tagName() == "radialGradient") { QRadialGradient *g = new QRadialGradient(); if (gradhelper.gradientUnits() == SvgGradientHelper::ObjectBoundingBox) { g->setCoordinateMode(QGradient::ObjectBoundingMode); g->setCenter(QPointF(SvgUtil::fromPercentage(b.attribute("cx", "50%")), SvgUtil::fromPercentage(b.attribute("cy", "50%")))); g->setRadius(SvgUtil::fromPercentage(b.attribute("r", "50%"))); g->setFocalPoint(QPointF(SvgUtil::fromPercentage(b.attribute("fx", "50%")), SvgUtil::fromPercentage(b.attribute("fy", "50%")))); } else { g->setCenter(QPointF(SvgUtil::fromUserSpace(b.attribute("cx").toDouble()), SvgUtil::fromUserSpace(b.attribute("cy").toDouble()))); g->setFocalPoint(QPointF(SvgUtil::fromUserSpace(b.attribute("fx").toDouble()), SvgUtil::fromUserSpace(b.attribute("fy").toDouble()))); g->setRadius(SvgUtil::fromUserSpace(b.attribute("r").toDouble())); } // preserve color stops if (gradhelper.gradient()) g->setStops(gradhelper.gradient()->stops()); gradhelper.setGradient(g); } else { return false; } // handle spread method QString spreadMethod = b.attribute("spreadMethod"); if (!spreadMethod.isEmpty()) { if (spreadMethod == "reflect") gradhelper.gradient()->setSpread(QGradient::ReflectSpread); else if (spreadMethod == "repeat") gradhelper.gradient()->setSpread(QGradient::RepeatSpread); else gradhelper.gradient()->setSpread(QGradient::PadSpread); } else gradhelper.gradient()->setSpread(QGradient::PadSpread); // Parse the color stops. The referencing gradient does not have colorstops, // so use the stops from the gradient it references to (e in this case and not b) m_context.styleParser().parseColorStops(gradhelper.gradient(), e); gradhelper.setTransform(SvgUtil::parseTransform(b.attribute("gradientTransform"))); m_gradients.insert(gradientId, gradhelper); return true; }