Krita Source Code Documentation
Loading...
Searching...
No Matches
KoStopGradient Class Reference

#include <KoStopGradient.h>

+ Inheritance diagram for KoStopGradient:

Public Member Functions

void bakeVariableColors (KoCanvasResourcesInterfaceSP canvasResourcesInterface) override
 
KoResourceSP clone () const override
 
void colorAt (KoColor &, qreal t) const override
 reimplemented
 
QString defaultFileExtension () const override
 reimplemented
 
 KoStopGradient (const KoStopGradient &rhs)
 
 KoStopGradient (const QString &filename=QString())
 
bool loadFromDevice (QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override
 
KoStopGradientoperator= (const KoStopGradient &rhs)=delete
 
bool operator== (const KoStopGradient &rhs) const
 
QList< int > requiredCanvasResources () const override
 
QPair< QString, QString > resourceType () const override
 
QString saveSvgGradient () const
 
bool saveToDevice (QIODevice *dev) const override
 
void setStops (QList< KoGradientStop > stops)
 Sets the gradient stops.
 
QList< KoGradientStopstops () const
 
bool stopsAt (KoGradientStop &leftStop, KoGradientStop &rightStop, qreal t) const
 Find stops surrounding position, returns false if position outside gradient.
 
QGradient * toQGradient () const override
 reimplemented
 
void toXML (QDomDocument &doc, QDomElement &gradientElt) const
 toXML Convert the gradient to an XML string.
 
void updateVariableColors (KoCanvasResourcesInterfaceSP canvasResourcesInterface) override
 
 ~KoStopGradient () override
 
- Public Member Functions inherited from KoAbstractGradient
KoAbstractGradientSP cloneAndBakeVariableColors (KoCanvasResourcesInterfaceSP canvasResourcesInterface) const
 
KoAbstractGradientSP cloneAndUpdateVariableColors (KoCanvasResourcesInterfaceSP canvasResourcesInterface) const
 
const KoColorSpacecolorSpace () const
 
QImage generatePreview (int width, int height) const
 
QImage generatePreview (int width, int height, KoCanvasResourcesInterfaceSP canvasResourcesInterface) const
 
 KoAbstractGradient (const KoAbstractGradient &rhs)
 
 KoAbstractGradient (const QString &filename)
 
void setColorSpace (KoColorSpace *colorSpace)
 
void setSpread (QGradient::Spread spreadMethod)
 
void setType (QGradient::Type repeatType)
 
QGradient::Spread spread () const
 
QGradient::Type type () const
 
void updatePreview ()
 
 ~KoAbstractGradient () override
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 
- Public Member Functions inherited from KoResource
bool active () const
 
void addMetaData (QString key, QVariant value)
 store the given key, value pair in the resource
 
virtual void clearSideLoadedResources ()
 
virtual QList< KoResourceLoadResultembeddedResources (KisResourcesInterfaceSP globalResourcesInterface) const
 
QString filename () const
 
QImage image () const
 
bool isDirty () const
 
virtual bool isEphemeral () const
 
virtual bool isSerializable () const
 
 KoResource ()
 
 KoResource (const KoResource &rhs)
 
 KoResource (const QString &filename)
 
virtual QList< KoResourceLoadResultlinkedResources (KisResourcesInterfaceSP globalResourcesInterface) const
 
bool load (KisResourcesInterfaceSP resourcesInterface)
 
QString md5Sum (bool generateIfEmpty=true) const
 
QMap< QString, QVariant > metadata () const
 get a map with all the metadata
 
virtual QString name () const
 
KoResourceoperator= (const KoResource &rhs)=delete
 
bool permanent () const
 
QList< KoResourceLoadResultrequiredResources (KisResourcesInterfaceSP globalResourcesInterface) const
 
int resourceId () const
 
bool save ()
 
void setActive (bool active)
 
void setDirty (bool value)
 Mark the preset as modified but not saved.
 
void setFilename (const QString &filename)
 
void setImage (const QImage &image)
 
void setMD5Sum (const QString &md5sum)
 Set the md5sum of this resource. It must be in hex-encoded string format.
 
void setName (const QString &name)
 
void setPermanent (bool permanent)
 
void setResourceId (int id)
 
void setStorageLocation (const QString &location)
 
void setValid (bool valid)
 
void setVersion (int version)
 
virtual QList< KoResourceLoadResultsideLoadedResources (KisResourcesInterfaceSP globalResourcesInterface) const
 
KoResourceSignature signature () const
 
QString storageLocation () const
 
QList< KoResourceLoadResulttakeSideLoadedResources (KisResourcesInterfaceSP globalResourcesInterface)
 
virtual QImage thumbnail () const
 thumbnail the thumbnail image to use in resource selectors
 
virtual QString thumbnailPath () const
 thumbnailPath returns the path to a separate thumbnail image, outside the actual resource file itself. If the path is relative, it is supposed start in the same location as the resource itself. If it's absolute, that is, it starts with "/", it is from the root of the storage.
 
virtual void updateThumbnail ()
 updateThumbnail updates the thumbnail for this resource. Reimplement if your thumbnail is something else than the image set with setImage.
 
bool valid () const
 
int version () const
 Get the version of the resource.
 
virtual ~KoResource ()
 

Static Public Member Functions

static QSharedPointer< KoStopGradientfromQGradient (const QGradient *gradient)
 Creates KoStopGradient from a QGradient.
 
static KoStopGradient fromXML (const QDomElement &elt)
 fromXML convert a gradient from xml.
 

Protected Attributes

QPointF m_focalPoint
 
bool m_hasVariableStops = false
 
QPointF m_start
 
QPointF m_stop
 
QList< KoGradientStopm_stops
 

Private Member Functions

void loadSvgGradient (QIODevice *file)
 
void parseSvgGradient (const QDomElement &element, QHash< QString, const KoColorProfile * > profiles)
 

Additional Inherited Members

- Public Attributes inherited from KoAbstractGradient
const KoColorSpacecolorSpace
 
QGradient::Spread spread
 
QGradient::Type type
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 
- Public Attributes inherited from KoResource
bool active {true}
 
QString filename
 
QImage image
 
QString md5sum
 
QMap< QString, QVariant > metadata
 
bool modified {false}
 
QString name
 
bool permanent {false}
 
int resourceId {-1}
 
QString storageLocation
 
bool valid {false}
 
int version {-1}
 

Detailed Description

Resource for colorstop based gradients like SVG gradients

Definition at line 89 of file KoStopGradient.h.

Constructor & Destructor Documentation

◆ KoStopGradient() [1/2]

KoStopGradient::KoStopGradient ( const QString & filename = QString())
explicit

Definition at line 39 of file KoStopGradient.cpp.

41{
42}
KoAbstractGradient(const QString &filename)
QString filename

◆ ~KoStopGradient()

KoStopGradient::~KoStopGradient ( )
override

Definition at line 44 of file KoStopGradient.cpp.

45{
46}

◆ KoStopGradient() [2/2]

KoStopGradient::KoStopGradient ( const KoStopGradient & rhs)

Definition at line 48 of file KoStopGradient.cpp.

50 , m_stops(rhs.m_stops)
51 , m_start(rhs.m_start)
52 , m_stop(rhs.m_stop)
54{
55}
QList< KoGradientStop > m_stops

Member Function Documentation

◆ bakeVariableColors()

void KoStopGradient::bakeVariableColors ( KoCanvasResourcesInterfaceSP canvasResourcesInterface)
overridevirtual

Reimplemented from KoAbstractGradient.

Definition at line 269 of file KoStopGradient.cpp.

270{
271 const KoColor fgColor = canvasResourcesInterface->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
272 const KoColor bgColor = canvasResourcesInterface->resource(KoCanvasResource::BackgroundColor).value<KoColor>();
273
274 for (auto it = m_stops.begin(); it != m_stops.end(); ++it) {
275 if (it->type == FOREGROUNDSTOP) {
276 it->color = fgColor;
277 it->type = COLORSTOP;
278 } else if (it->type == BACKGROUNDSTOP) {
279 it->color = bgColor;
280 it->type = COLORSTOP;
281 }
282 }
283}
@ FOREGROUNDSTOP
@ BACKGROUNDSTOP
@ COLORSTOP
@ BackgroundColor
The active background color selected for this canvas.
@ ForegroundColor
The active foreground color selected for this canvas.

References KoCanvasResource::BackgroundColor, BACKGROUNDSTOP, COLORSTOP, KoCanvasResource::ForegroundColor, FOREGROUNDSTOP, and m_stops.

◆ clone()

KoResourceSP KoStopGradient::clone ( ) const
overridevirtual

Implements KoResource.

Definition at line 69 of file KoStopGradient.cpp.

70{
71 return KoResourceSP(new KoStopGradient(*this));
72}
KoStopGradient(const QString &filename=QString())
QSharedPointer< KoResource > KoResourceSP

References KoStopGradient().

◆ colorAt()

void KoStopGradient::colorAt ( KoColor & dst,
qreal t ) const
overridevirtual

reimplemented

Reimplemented from KoAbstractGradient.

Definition at line 154 of file KoStopGradient.cpp.

155{
156 KoGradientStop leftStop, rightStop;
157 if (!stopsAt(leftStop, rightStop, t)) return;
158
159 const KoColorSpace *mixSpace = dst.colorSpace();
160
161 KoColor buffer(mixSpace);
162 KoColor startDummy(leftStop.color, mixSpace);
163 KoColor endDummy(rightStop.color, mixSpace);
164
165 const std::array<quint8 *, 2> colors = {{startDummy.data(), endDummy.data()}};
166
167 qreal localT = NAN;
168 qreal stopDistance = rightStop.position - leftStop.position;
169 if (stopDistance < DBL_EPSILON) {
170 localT = 0.5;
171 } else {
172 localT = (t - leftStop.position) / stopDistance;
173 }
174 std::array<qint16, 2> colorWeights {};
175 colorWeights[0] = std::lround((1.0 - localT) * qint16_MAX);
176 colorWeights[1] = qint16_MAX - colorWeights[0];
177
178 mixSpace->mixColorsOp()->mixColors(colors.data(), colorWeights.data(), 2, buffer.data(), qint16_MAX);
179
180 dst = buffer;
181}
KoMixColorsOp * mixColorsOp
const KoColorSpace * colorSpace() const
return the current colorSpace
Definition KoColor.h:82
virtual void mixColors(const quint8 *const *colors, const qint16 *weights, int nColors, quint8 *dst, int weightSum=255) const =0
bool stopsAt(KoGradientStop &leftStop, KoGradientStop &rightStop, qreal t) const
Find stops surrounding position, returns false if position outside gradient.
const qint16 qint16_MAX
Definition kis_global.h:28

References KoGradientStop::color, KoColor::colorSpace(), KoColor::data(), KoMixColorsOp::mixColors(), KoColorSpace::mixColorsOp, KoGradientStop::position, qint16_MAX, and stopsAt().

◆ defaultFileExtension()

QString KoStopGradient::defaultFileExtension ( ) const
overridevirtual

reimplemented

Reimplemented from KoResource.

Definition at line 543 of file KoStopGradient.cpp.

544{
545 return QString(".svg");
546}

◆ fromQGradient()

QSharedPointer< KoStopGradient > KoStopGradient::fromQGradient ( const QGradient * gradient)
static

Creates KoStopGradient from a QGradient.

Definition at line 183 of file KoStopGradient.cpp.

184{
185 if (!gradient)
187
188 QSharedPointer<KoStopGradient> newGradient(new KoStopGradient(QString()));
189 newGradient->setType(gradient->type());
190 newGradient->setSpread(gradient->spread());
191
192 switch (gradient->type()) {
193 case QGradient::LinearGradient: {
194 const QLinearGradient* g = static_cast<const QLinearGradient*>(gradient);
195 newGradient->m_start = g->start();
196 newGradient->m_stop = g->finalStop();
197 newGradient->m_focalPoint = g->start();
198 break;
199 }
200 case QGradient::RadialGradient: {
201 const QRadialGradient* g = static_cast<const QRadialGradient*>(gradient);
202 newGradient->m_start = g->center();
203 newGradient->m_stop = g->center() + QPointF(g->radius(), 0);
204 newGradient->m_focalPoint = g->focalPoint();
205 break;
206 }
207 case QGradient::ConicalGradient: {
208 const QConicalGradient* g = static_cast<const QConicalGradient*>(gradient);
209 qreal radian = g->angle() * M_PI / 180.0;
210 newGradient->m_start = g->center();
211 newGradient->m_stop = QPointF(100.0 * cos(radian), 100.0 * sin(radian));
212 newGradient->m_focalPoint = g->center();
213 break;
214 }
215 default:
217 }
218
219 Q_FOREACH(const QGradientStop & stop, gradient->stops()) {
220 KoColor color(newGradient->colorSpace());
221 color.fromQColor(stop.second);
222 newGradient->m_stops.append(KoGradientStop(stop.first, color, COLORSTOP));
223 }
224
225 newGradient->setValid(true);
226
227 return newGradient;
228}
#define M_PI
Definition kis_global.h:111

References COLORSTOP, KoColor::fromQColor(), KoStopGradient(), and M_PI.

◆ fromXML()

KoStopGradient KoStopGradient::fromXML ( const QDomElement & elt)
static

fromXML convert a gradient from xml.

Returns
a gradient.

Definition at line 563 of file KoStopGradient.cpp.

564{
565 KoStopGradient gradient;
567 QDomElement stopElt = elt.firstChildElement("stop");
568 while (!stopElt.isNull()) {
569 qreal offset = KisDomUtils::toDouble(stopElt.attribute("offset", "0.0"));
570 QString bitDepth = stopElt.attribute("bitdepth", Integer8BitsColorDepthID.id());
571 KoColor color = KoColor::fromXML(stopElt.firstChildElement(), bitDepth);
572 color.setOpacity(KisDomUtils::toDouble(stopElt.attribute("alpha", "1.0")));
573 KoGradientStopType stoptype = static_cast<KoGradientStopType>(KisDomUtils::toInt(stopElt.attribute("stoptype", "0")));
574 stops.append(KoGradientStop(offset, color, stoptype));
575 stopElt = stopElt.nextSiblingElement("stop");
576 }
577 gradient.setStops(stops);
578 return gradient;
579}
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
KoGradientStopType
static KoColor fromXML(const QDomElement &elt, const QString &channelDepthId)
Definition KoColor.cpp:350
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
QString id() const
Definition KoID.cpp:63
void setStops(QList< KoGradientStop > stops)
Sets the gradient stops.
QList< KoGradientStop > stops() const
double toDouble(const QString &str, bool *ok=nullptr)
int toInt(const QString &str, bool *ok=nullptr)

References KoColor::fromXML(), KoID::id(), Integer8BitsColorDepthID, KoColor::setOpacity(), setStops(), stops(), KisDomUtils::toDouble(), and KisDomUtils::toInt().

◆ loadFromDevice()

bool KoStopGradient::loadFromDevice ( QIODevice * dev,
KisResourcesInterfaceSP resourcesInterface )
overridevirtual

Implements KoResource.

Definition at line 74 of file KoStopGradient.cpp.

75{
76 Q_UNUSED(resourcesInterface);
77 loadSvgGradient(dev);
78 if (m_stops.count() >= 2) {
79 setValid(true);
80 }
82 return true;
83}
void loadSvgGradient(QIODevice *file)
void setValid(bool valid)

References loadSvgGradient(), m_stops, KoResource::setValid(), and KoAbstractGradient::updatePreview().

◆ loadSvgGradient()

void KoStopGradient::loadSvgGradient ( QIODevice * file)
private

Definition at line 299 of file KoStopGradient.cpp.

300{
301 QDomDocument doc;
302
303 if (!(doc.setContent(file))) {
304 file->close();
305 } else {
306 QHash<QString, const KoColorProfile*> profiles;
307 for (QDomElement e = doc.documentElement().firstChildElement("defs"); !e.isNull(); e = e.nextSiblingElement("defs")) {
308 for (QDomElement profileEl = e.firstChildElement("color-profile"); !profileEl.isNull(); profileEl = profileEl.nextSiblingElement("color-profile")) {
309 const QString href = profileEl.attribute("xlink:href");
310 const QByteArray uniqueId = QByteArray::fromHex(profileEl.attribute("local").toLatin1());
311 const QString name = profileEl.attribute("name");
312
313 const KoColorProfile *profile =
315 if (!profile) {
316 QFile file(href);
317 if (file.size() > 0 && file.open(QIODevice::ReadOnly)) {
319 KIS_ASSERT(engine);
320 profile = engine->addProfile(href);
321 }
322 }
323
324
325 if (profile && !profiles.contains(name)) {
326 profiles.insert(name, profile);
327 }
328 }
329 }
330 for (QDomNode n = doc.documentElement().firstChild(); !n.isNull(); n = n.nextSibling()) {
331 QDomElement e = n.toElement();
332
333 if (e.isNull()) continue;
334
335 if (e.tagName() == "linearGradient" || e.tagName() == "radialGradient") {
336 parseSvgGradient(e, profiles);
337 return;
338 }
339 // Inkscape gradients are in another defs
340 if (e.tagName() == "defs") {
341
342
343 for (QDomNode defnode = e.firstChild(); !defnode.isNull(); defnode = defnode.nextSibling()) {
344 QDomElement defelement = defnode.toElement();
345
346 if (defelement.isNull()) continue;
347
348 if (defelement.tagName() == "linearGradient" || defelement.tagName() == "radialGradient") {
349 parseSvgGradient(defelement, profiles);
350 return;
351 }
352 }
353 }
354 }
355 }
356}
static KoColorSpaceEngineRegistry * instance()
T get(const QString &id) const
void parseSvgGradient(const QDomElement &element, QHash< QString, const KoColorProfile * > profiles)
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
virtual const KoColorProfile * addProfile(const QString &filename)=0
static KoColorSpaceRegistry * instance()
const KoColorProfile * profileByUniqueId(const QByteArray &id) const
QString name

References KoColorSpaceEngine::addProfile(), KoGenericRegistry< T >::get(), KoColorSpaceEngineRegistry::instance(), KoColorSpaceRegistry::instance(), KIS_ASSERT, KoResource::name, parseSvgGradient(), and KoColorSpaceRegistry::profileByUniqueId().

◆ operator=()

KoStopGradient & KoStopGradient::operator= ( const KoStopGradient & rhs)
delete

◆ operator==()

bool KoStopGradient::operator== ( const KoStopGradient & rhs) const

Definition at line 57 of file KoStopGradient.cpp.

58{
59 return
60 *colorSpace() == *rhs.colorSpace() &&
61 spread() == rhs.spread() &&
62 type() == rhs.type() &&
63 m_start == rhs.m_start &&
64 m_stop == rhs.m_stop &&
66 m_stops == rhs.m_stops;
67}
const KoColorSpace * colorSpace
QGradient::Spread spread

References KoAbstractGradient::colorSpace, m_focalPoint, m_start, m_stop, m_stops, KoAbstractGradient::spread, and KoAbstractGradient::type.

◆ parseSvgGradient()

void KoStopGradient::parseSvgGradient ( const QDomElement & element,
QHash< QString, const KoColorProfile * > profiles )
private

Definition at line 359 of file KoStopGradient.cpp.

360{
361 m_stops.clear();
362 m_hasVariableStops = false;
363 setSpread(QGradient::PadSpread);
364
365 /*QString href = e.attribute( "xlink:href" ).mid( 1 );
366 if( !href.isEmpty() )
367 {
368 }*/
369 setName(element.attribute("id", i18n("SVG Gradient")));
370
371 bool bbox = element.attribute("gradientUnits") != "userSpaceOnUse";
372
373 if (element.tagName() == "linearGradient") {
374
375 if (bbox) {
376 QString s;
377
378 s = element.attribute("x1", "0%");
379 qreal xOrigin;
380 if (s.endsWith('%'))
381 xOrigin = s.remove('%').toDouble();
382 else
383 xOrigin = s.toDouble() * 100.0;
384
385 s = element.attribute("y1", "0%");
386 qreal yOrigin;
387 if (s.endsWith('%'))
388 yOrigin = s.remove('%').toDouble();
389 else
390 yOrigin = s.toDouble() * 100.0;
391
392 s = element.attribute("x2", "100%");
393 qreal xVector;
394 if (s.endsWith('%'))
395 xVector = s.remove('%').toDouble();
396 else
397 xVector = s.toDouble() * 100.0;
398
399 s = element.attribute("y2", "0%");
400 qreal yVector;
401 if (s.endsWith('%'))
402 yVector = s.remove('%').toDouble();
403 else
404 yVector = s.toDouble() * 100.0;
405
406 m_start = QPointF(xOrigin, yOrigin);
407 m_stop = QPointF(xVector, yVector);
408 }
409 else {
410 m_start = QPointF(element.attribute("x1").toDouble(), element.attribute("y1").toDouble());
411 m_stop = QPointF(element.attribute("x2").toDouble(), element.attribute("y2").toDouble());
412 }
413 setType(QGradient::LinearGradient);
414 }
415 else {
416 if (bbox) {
417 QString s;
418
419 s = element.attribute("cx", "50%");
420 qreal xOrigin;
421 if (s.endsWith('%'))
422 xOrigin = s.remove('%').toDouble();
423 else
424 xOrigin = s.toDouble() * 100.0;
425
426 s = element.attribute("cy", "50%");
427 qreal yOrigin;
428 if (s.endsWith('%'))
429 yOrigin = s.remove('%').toDouble();
430 else
431 yOrigin = s.toDouble() * 100.0;
432
433 s = element.attribute("cx", "50%");
434 qreal xVector;
435 if (s.endsWith('%'))
436 xVector = s.remove('%').toDouble();
437 else
438 xVector = s.toDouble() * 100.0;
439
440 s = element.attribute("r", "50%");
441 if (s.endsWith('%'))
442 xVector += s.remove('%').toDouble();
443 else
444 xVector += s.toDouble() * 100.0;
445
446 s = element.attribute("cy", "50%");
447 qreal yVector;
448 if (s.endsWith('%'))
449 yVector = s.remove('%').toDouble();
450 else
451 yVector = s.toDouble() * 100.0;
452
453 s = element.attribute("fx", "50%");
454 qreal xFocal;
455 if (s.endsWith('%'))
456 xFocal = s.remove('%').toDouble();
457 else
458 xFocal = s.toDouble() * 100.0;
459
460 s = element.attribute("fy", "50%");
461 qreal yFocal;
462 if (s.endsWith('%'))
463 yFocal = s.remove('%').toDouble();
464 else
465 yFocal = s.toDouble() * 100.0;
466
467 m_start = QPointF(xOrigin, yOrigin);
468 m_stop = QPointF(xVector, yVector);
469 m_focalPoint = QPointF(xFocal, yFocal);
470 }
471 else {
472 m_start = QPointF(element.attribute("cx").toDouble(), element.attribute("cy").toDouble());
473 m_stop = QPointF(element.attribute("cx").toDouble() + element.attribute("r").toDouble(),
474 element.attribute("cy").toDouble());
475 m_focalPoint = QPointF(element.attribute("fx").toDouble(), element.attribute("fy").toDouble());
476 }
477 setType(QGradient::RadialGradient);
478 }
479 // handle spread method
480 QString spreadMethod = element.attribute("spreadMethod");
481 if (!spreadMethod.isEmpty()) {
482 if (spreadMethod == "reflect")
483 setSpread(QGradient::ReflectSpread);
484 else if (spreadMethod == "repeat")
485 setSpread(QGradient::RepeatSpread);
486 }
487
488 for (QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling()) {
489 QDomElement colorstop = n.toElement();
490 if (colorstop.tagName() == "stop") {
491 qreal opacity = 0.0;
492 KoColor color;
493 float off;
494 QString temp = colorstop.attribute("offset");
495 if (temp.contains('%')) {
496 temp = temp.left(temp.length() - 1);
497 off = temp.toFloat() / 100.0;
498 }
499 else
500 off = temp.toFloat();
501
502 if (!colorstop.attribute("stop-color").isEmpty())
503 color = KoColor::fromSVG11(colorstop.attribute("stop-color"), profiles);
504 else {
505 // try style attr
506 QString style = colorstop.attribute("style").simplified();
507 QStringList substyles = style.split(';', Qt::SkipEmptyParts);
508 Q_FOREACH(const QString & s, substyles) {
509 QStringList substyle = s.split(':');
510 QString command = substyle[0].trimmed();
511 QString params = substyle[1].trimmed();
512 if (command == "stop-color")
513 color = KoColor::fromSVG11(params, profiles);
514 if (command == "stop-opacity")
515 opacity = params.toDouble();
516 }
517
518 }
519 if (!colorstop.attribute("stop-opacity").isEmpty())
520 opacity = colorstop.attribute("stop-opacity").toDouble();
521
522 color.setOpacity(static_cast<quint8>(std::lround(opacity * OPACITY_OPAQUE_U8)));
523 QString stopTypeStr = colorstop.attribute("krita:stop-type", "color-stop");
525 if (stopType != COLORSTOP) {
526 m_hasVariableStops = true;
527 }
528 //According to the SVG spec each gradient offset has to be equal to or greater than the previous one
529 //if not it needs to be adjusted to be equal
530 if (m_stops.count() > 0 && m_stops.last().position >= off) {
531 off = m_stops.last().position;
532 }
533 m_stops.append(KoGradientStop(off, color, stopType));
534 }
535 }
536 if (m_stops.count() >= 2) {
537 setValid(true);
538 } else {
539 setValid(false);
540 }
541}
const quint8 OPACITY_OPAQUE_U8
static KoColor fromSVG11(const QString value, QHash< QString, const KoColorProfile * > profileList, KoColor current=KoColor())
fromSVG11 Parses a color attribute value and returns a KoColor. SVG defines the colorprofiles elsewhe...
Definition KoColor.cpp:530
void setSpread(QGradient::Spread spreadMethod)
void setType(QGradient::Type repeatType)
static KoGradientStopType typeFromString(QString typestring)
void setName(const QString &name)

References COLORSTOP, KoColor::fromSVG11(), m_focalPoint, m_hasVariableStops, m_start, m_stop, m_stops, OPACITY_OPAQUE_U8, KoResource::setName(), KoColor::setOpacity(), KoAbstractGradient::setSpread(), KoAbstractGradient::setType(), KoResource::setValid(), and KoGradientStop::typeFromString().

◆ requiredCanvasResources()

QList< int > KoStopGradient::requiredCanvasResources ( ) const
overridevirtual

A list of per-canvas active resources that are needed for this resource to function properly. E.g. some gradients may require Fg/Bg colors and some presets would like to know about the current gradient selection.

Returns
a list of canvas resources needed for the current resource

Reimplemented from KoResource.

Definition at line 255 of file KoStopGradient.cpp.

256{
257 QList<int> result;
258
259 if (std::find_if_not(m_stops.begin(), m_stops.end(),
261 != m_stops.end()) {
262
264 }
265
266 return result;
267}
auto mem_equal_to(MemTypeNoRef Class::*ptr, MemType &&value)
mem_equal_to is an unary functor that compares a member of the object to a given value
Definition KisMpl.h:233
KoGradientStopType type

References KoCanvasResource::BackgroundColor, COLORSTOP, KoCanvasResource::ForegroundColor, m_stops, kismpl::mem_equal_to(), and KoGradientStop::type.

◆ resourceType()

QPair< QString, QString > KoStopGradient::resourceType ( ) const
inlineoverridevirtual
Returns
the resource type

Implements KoResource.

Definition at line 104 of file KoStopGradient.h.

104 {
105 return QPair<QString, QString>(ResourceType::Gradients, ResourceSubType::StopGradients);
106 }
const QString StopGradients
const QString Gradients

References ResourceType::Gradients, and ResourceSubType::StopGradients.

◆ saveSvgGradient()

QString KoStopGradient::saveSvgGradient ( ) const

Definition at line 581 of file KoStopGradient.cpp.

582{
583 QDomDocument doc;
584
585 doc.setContent(QString("<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:krita=\"%1\" > </svg>").arg(KoXmlNS::krita));
586
587 const QString spreadMethod[3] = {
588 QString("pad"),
589 QString("reflect"),
590 QString("repeat")
591 };
592
593 QDomElement gradient = doc.createElement("linearGradient");
594 gradient.setAttribute("id", name());
595 gradient.setAttribute("gradientUnits", "objectBoundingBox");
596 gradient.setAttribute("spreadMethod", spreadMethod[spread()]);
597
598 QHash<QString, const KoColorProfile*> profiles;
599 for(const KoGradientStop & stop: m_stops) {
600 QDomElement stopEl = doc.createElement("stop");
601 stopEl.setAttribute("stop-color", stop.color.toSVG11(&profiles));
602 stopEl.setAttribute("offset", QString().setNum(stop.position));
603 stopEl.setAttribute("stop-opacity", stop.color.opacityF());
604 stopEl.setAttribute("krita:stop-type", stop.typeString());
605 gradient.appendChild(stopEl);
606 }
607
608 if (profiles.size()>0) {
609 QDomElement defs = doc.createElement("defs");
610 for (QString key: profiles.keys()) {
611 const KoColorProfile * profile = profiles.value(key);
612
613 QDomElement profileEl = doc.createElement("color-profile");
614 profileEl.setAttribute("name", key);
615 QString val = profile->uniqueId().toHex();
616 profileEl.setAttribute("local", val);
617 profileEl.setAttribute("xlink:href", profile->fileName());
618 defs.appendChild(profileEl);
619 }
620 doc.documentElement().appendChild(defs);
621 }
622
623 doc.documentElement().appendChild(gradient);
624
625 return doc.toString();
626}
static const QString krita
Definition KoXmlNS.h:48
virtual QByteArray uniqueId() const =0

References KoColorProfile::fileName, KoXmlNS::krita, m_stops, KoResource::name, KoAbstractGradient::spread, and KoColorProfile::uniqueId().

◆ saveToDevice()

bool KoStopGradient::saveToDevice ( QIODevice * dev) const
overridevirtual

Reimplemented from KoResource.

Definition at line 628 of file KoStopGradient.cpp.

629{
630 QTextStream stream(dev);
632 stream << saveSvgGradient();
633
634 return true;
635}
QString saveSvgGradient() const
void setUtf8OnStream(QTextStream &stream)

References saveSvgGradient(), and KisPortingUtils::setUtf8OnStream().

◆ setStops()

void KoStopGradient::setStops ( QList< KoGradientStop > stops)

Sets the gradient stops.

Definition at line 230 of file KoStopGradient.cpp.

231{
232 m_stops.clear();
233 m_hasVariableStops = false;
234 KoColor color;
235 Q_FOREACH(const KoGradientStop & stop, stops) {
236 color = stop.color;
237 m_stops.append(KoGradientStop(stop.position, color, stop.type));
238 if (stop.type != COLORSTOP) {
239 m_hasVariableStops = true;
240 }
241 }
242 if (m_stops.count() >= 2) {
243 setValid(true);
244 } else {
245 setValid(false);
246 }
248}

References KoGradientStop::color, COLORSTOP, m_hasVariableStops, m_stops, KoGradientStop::position, KoResource::setValid(), stops(), KoGradientStop::type, and KoAbstractGradient::updatePreview().

◆ stops()

QList< KoGradientStop > KoStopGradient::stops ( ) const

Definition at line 250 of file KoStopGradient.cpp.

251{
252 return m_stops;
253}

References m_stops.

◆ stopsAt()

bool KoStopGradient::stopsAt ( KoGradientStop & leftStop,
KoGradientStop & rightStop,
qreal t ) const

Find stops surrounding position, returns false if position outside gradient.

Definition at line 122 of file KoStopGradient.cpp.

123{
124 if (!m_stops.count())
125 return false;
126
127 KIS_SAFE_ASSERT_RECOVER(!qIsNaN(t)) { // if it's nan, it would crash in the last 'else'
128 leftStop = m_stops.first();
129 rightStop = KoGradientStop(-std::numeric_limits<double>::infinity(), leftStop.color, leftStop.type);
130 return true;
131 }
132
133 if (t <= m_stops.first().position || m_stops.count() == 1) {
134 // we have only one stop or t is before the first stop
135 leftStop = m_stops.first();
136 rightStop = KoGradientStop(-std::numeric_limits<double>::infinity(), leftStop.color, leftStop.type);
137 return true;
138 } else if (t >= m_stops.last().position) {
139 // t is after the last stop
140 rightStop = m_stops.last();
141 leftStop = KoGradientStop(std::numeric_limits<double>::infinity(), rightStop.color, rightStop.type);
142 return true;
143 } else {
144 // we have at least two color stops
145 // -> find the two stops which frame our t
146 auto it = std::lower_bound(m_stops.begin(), m_stops.end(), KoGradientStop(t, KoColor(), COLORSTOP),
148 leftStop = *(it - 1);
149 rightStop = *(it);
150 return true;
151 }
152}
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
auto mem_less(MemTypeNoRef Class::*ptr, MemType &&value)
mem_less is an unary functor that compares a member of the object to a given value
Definition KisMpl.h:269

References KoGradientStop::color, COLORSTOP, KIS_SAFE_ASSERT_RECOVER, m_stops, kismpl::mem_less(), KoGradientStop::position, and KoGradientStop::type.

◆ toQGradient()

QGradient * KoStopGradient::toQGradient ( ) const
overridevirtual

reimplemented

Reimplemented from KoAbstractGradient.

Definition at line 85 of file KoStopGradient.cpp.

86{
87 QGradient* gradient;
88
89 switch (type()) {
90 case QGradient::LinearGradient: {
91 gradient = new QLinearGradient(m_start, m_stop);
92 break;
93 }
94 case QGradient::RadialGradient: {
95 QPointF diff = m_stop - m_start;
96 qreal radius = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
97 gradient = new QRadialGradient(m_start, radius, m_focalPoint);
98 break;
99 }
100 case QGradient::ConicalGradient: {
101 qreal angle = atan2(m_start.y(), m_start.x()) * 180.0 / M_PI;
102 if (angle < 0.0)
103 angle += 360.0;
104 gradient = new QConicalGradient(m_start, angle);
105 break;
106 }
107 default:
108 return 0;
109 }
110 QColor color;
111 for (QList<KoGradientStop>::const_iterator i = m_stops.begin(); i != m_stops.end(); ++i) {
112 i->color.toQColor(&color);
113 gradient->setColorAt(i->position, color);
114 }
115
116 gradient->setCoordinateMode(QGradient::ObjectBoundingMode);
117 gradient->setSpread(this->spread());
118
119 return gradient;
120}
KRITAIMAGE_EXPORT qreal atan2(qreal y, qreal x)
atan2 replacement

References m_focalPoint, M_PI, m_start, m_stop, m_stops, KoAbstractGradient::spread, and KoAbstractGradient::type.

◆ toXML()

void KoStopGradient::toXML ( QDomDocument & doc,
QDomElement & gradientElt ) const

toXML Convert the gradient to an XML string.

Definition at line 548 of file KoStopGradient.cpp.

549{
550 gradientElt.setAttribute("type", "stop");
551 for (int s = 0; s < m_stops.size(); s++) {
552 KoGradientStop stop = m_stops.at(s);
553 QDomElement stopElt = doc.createElement("stop");
554 stopElt.setAttribute("offset", KisDomUtils::toString(stop.position));
555 stopElt.setAttribute("bitdepth", stop.color.colorSpace()->colorDepthId().id());
556 stopElt.setAttribute("alpha", KisDomUtils::toString(stop.color.opacityF()));
557 stopElt.setAttribute("stoptype", KisDomUtils::toString(stop.type));
558 stop.color.toXML(doc, stopElt);
559 gradientElt.appendChild(stopElt);
560 }
561}
virtual KoID colorDepthId() const =0
qreal opacityF() const
Definition KoColor.cpp:345
void toXML(QDomDocument &doc, QDomElement &colorElt) const
Definition KoColor.cpp:304
QString toString(const QString &value)

References KoGradientStop::color, KoColorSpace::colorDepthId(), KoColor::colorSpace(), KoID::id(), m_stops, KoColor::opacityF(), KoGradientStop::position, KisDomUtils::toString(), KoColor::toXML(), and KoGradientStop::type.

◆ updateVariableColors()

void KoStopGradient::updateVariableColors ( KoCanvasResourcesInterfaceSP canvasResourcesInterface)
overridevirtual

Reimplemented from KoAbstractGradient.

Definition at line 285 of file KoStopGradient.cpp.

286{
287 const KoColor fgColor = canvasResourcesInterface->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
288 const KoColor bgColor = canvasResourcesInterface->resource(KoCanvasResource::BackgroundColor).value<KoColor>();
289
290 for (auto it = m_stops.begin(); it != m_stops.end(); ++it) {
291 if (it->type == FOREGROUNDSTOP) {
292 it->color = fgColor;
293 } else if (it->type == BACKGROUNDSTOP) {
294 it->color = bgColor;
295 }
296 }
297}

References KoCanvasResource::BackgroundColor, BACKGROUNDSTOP, KoCanvasResource::ForegroundColor, FOREGROUNDSTOP, and m_stops.

Member Data Documentation

◆ m_focalPoint

QPointF KoStopGradient::m_focalPoint
protected

Definition at line 152 of file KoStopGradient.h.

◆ m_hasVariableStops

bool KoStopGradient::m_hasVariableStops = false
protected

Definition at line 149 of file KoStopGradient.h.

◆ m_start

QPointF KoStopGradient::m_start
protected

Definition at line 150 of file KoStopGradient.h.

◆ m_stop

QPointF KoStopGradient::m_stop
protected

Definition at line 151 of file KoStopGradient.h.

◆ m_stops

QList<KoGradientStop> KoStopGradient::m_stops
protected

Definition at line 148 of file KoStopGradient.h.


The documentation for this class was generated from the following files: