Krita Source Code Documentation
Loading...
Searching...
No Matches
psd_layer_gradient_fill Struct Reference

#include <psd_additional_layer_info_block.h>

Public Member Functions

QDomDocument getASLXML ()
 
QSharedPointer< KoShapeBackgroundgetBackground ()
 
QBrush getBrush ()
 
QDomDocument getFillLayerConfig ()
 
QGradient * getGradient ()
 
bool loadFromConfig (KisFilterConfigurationSP cfg)
 
void setAlignWithLayer (bool align)
 
void setAngle (float Angl)
 
void setDither (bool Dthr)
 
void setFromQGradient (const QGradient *gradient)
 
void setGradient (const KoAbstractGradientSP &newGradient)
 
void setOffset (QPointF Ofst)
 
void setReverse (bool Rvrs)
 
void setScale (float Scl)
 
void setType (const QString type)
 
bool svgCompatible ()
 
void writeASL (KisAslXmlWriter &w)
 

Static Public Member Functions

static void setupCatcher (const QString path, KisAslCallbackObjectCatcher &catcher, psd_layer_gradient_fill *data)
 

Public Attributes

bool align_with_layer {false}
 
double angle {0.0}
 
bool dithered {false}
 
QDomDocument gradient
 
int imageHeight {1}
 
int imageWidth {1}
 
QPointF offset
 
QString repeat {QString("none")}
 
bool reverse {false}
 
double scale {100.0}
 
QString style {QString("linear")}
 

Detailed Description

Definition at line 239 of file psd_additional_layer_info_block.h.

Member Function Documentation

◆ getASLXML()

QDomDocument psd_layer_gradient_fill::getASLXML ( )
inline

Definition at line 469 of file psd_additional_layer_info_block.h.

469 {
471 w.enterDescriptor("", "", "null");
472 writeASL(w);
473
474 w.leaveDescriptor();
475
476 return w.document();
477 }

◆ getBackground()

QSharedPointer< KoShapeBackground > psd_layer_gradient_fill::getBackground ( )
inline

Definition at line 622 of file psd_additional_layer_info_block.h.

◆ getBrush()

QBrush psd_layer_gradient_fill::getBrush ( )
inline

Definition at line 520 of file psd_additional_layer_info_block.h.

520 {
521 QGradient *grad = getGradient();
522 if (grad) {
523 QBrush brush = *grad;
524 return brush;
525 }
526 return QBrush(Qt::transparent);
527 }

◆ getFillLayerConfig()

QDomDocument psd_layer_gradient_fill::getFillLayerConfig ( )
inline

Definition at line 321 of file psd_additional_layer_info_block.h.

321 {
324 cfg->setProperty("gradient", gradient.toString());
325 cfg->setProperty("dither", dithered);
326 cfg->setProperty("reverse", reverse);
327
328 cfg->setProperty("shape", style);
329 cfg->setProperty("repeat", repeat);
330
331 cfg->setProperty("end_position_coordinate_system", "polar");
332
333 cfg->setProperty("end_position_distance_units", "percent_of_width");
334 cfg->setProperty("start_position_x_units", "percent_of_width");
335 cfg->setProperty("start_position_y_units", "percent_of_height");
336
337 // angle seems to go from -180 to +180;
338 double fixedAngle = fmod(360.0 + angle, 360.0);
339
340 double scaleModifier = 1.0;
341
342 if (style == "square") {
343 fixedAngle = fmod((45.0 + fixedAngle), 360.0);
344
345 scaleModifier = cos(kisDegreesToRadians(45.0));
346 double halfAngle = fmod(fabs(fixedAngle), 180.0);
347 scaleModifier *= 1/cos(kisDegreesToRadians(45.0 - fmod(halfAngle, 45.0) ));
348 if (halfAngle >= 45.0 && halfAngle < 135.0) {
349 scaleModifier = (scaleModifier) * (imageHeight / imageWidth);
350 }
351
352 } else {
353 double halfAngle = fmod(fabs(fixedAngle), 180.0);
354 scaleModifier *= 1/cos(kisDegreesToRadians(halfAngle));
355 if (halfAngle >= 45.0 && halfAngle < 135.0) {
356 scaleModifier = (scaleModifier) * (imageHeight / imageWidth);
357 }
358
359 }
360
361 cfg->setProperty("end_position_angle", fixedAngle);
362
363 if (style == "linear") {
364 // linear has the problem that in Krita it rotates around the top-left,
365 // while in psd it rotates around the middle.
366 QPointF center(imageWidth*0.5, imageHeight*0.5);
367
368 QTransform rotate;
369 rotate.rotate(fixedAngle);
370 QTransform tf = QTransform::fromTranslate(-center.x(), -center.y())
371 * rotate * QTransform::fromTranslate(center.x(), center.y());
372 QPointF topleft = tf.inverted().map(QPointF(0.0, 0.0));
373 double xPercentage = (topleft.x()/double(imageWidth)) * 100.0;
374 double yPercentage = (topleft.y()/double(imageHeight)) * 100.0;
375
376 cfg->setProperty("end_position_distance", scale * scaleModifier);
377 cfg->setProperty("start_position_x", xPercentage + offset.x());
378 cfg->setProperty("start_position_y", yPercentage + offset.y());
379 } else {
380 cfg->setProperty("end_position_distance", scale * 0.5 * fabs(scaleModifier));
381 cfg->setProperty("start_position_x", (50.0)+offset.x());
382 cfg->setProperty("start_position_y", (50.0)+offset.y());
383 }
384
385 QDomDocument doc;
386 doc.setContent(cfg->toXML());
387 return doc;
388 }
static KisGeneratorRegistry * instance()
static KisResourcesInterfaceSP instance()
const T value(const QString &id) const
T kisDegreesToRadians(T degrees)
Definition kis_global.h:176
virtual KisFilterConfigurationSP defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const

References KisBaseProcessor::defaultConfiguration(), KisGeneratorRegistry::instance(), KisGlobalResourcesInterface::instance(), kisDegreesToRadians(), and KoGenericRegistry< T >::value().

◆ getGradient()

QGradient * psd_layer_gradient_fill::getGradient ( )
inline

Definition at line 528 of file psd_additional_layer_info_block.h.

528 {
529 QGradient *pointer = nullptr;
530 if (!gradient.isNull()) {
531 const QDomElement gradientElement = gradient.firstChildElement();
532 if (!gradientElement.isNull()) {
533 const QString gradientType = gradientElement.attribute("type");
534 if (gradientType == "stop") {
535 const KoStopGradient grad = KoStopGradient::fromXML(gradientElement);
536 if (grad.valid()) {
537 pointer = grad.toQGradient();
538 }
539 } else if (gradientType == "segment") {
540 const KoSegmentGradient grad = KoSegmentGradient::fromXML(gradientElement);
541 if (grad.valid()) {
542 pointer = grad.toQGradient();
543 }
544 }
545 }
546 }
547 if (pointer) {
548 QGradient::CoordinateMode mode = QGradient::ObjectBoundingMode;
549 pointer->setCoordinateMode(mode);
550
551 if (reverse) {
552 QGradientStops newStops;
553 Q_FOREACH(QGradientStop stop, pointer->stops()) {
554 newStops.append(QPair<double, QColor>(1.0-stop.first, stop.second));
555 }
556 pointer->setStops(newStops);
557 }
558
559 QLinearGradient *g = static_cast<QLinearGradient*>(pointer);
560 QLineF line = QLineF::fromPolar(0.5*(scale*0.01), angle);
561 line.translate(QPointF(0.5, 0.5)+(offset*0.01));
562
563 if (style == "radial") {
564 QRadialGradient *r = new QRadialGradient(line.p1(), line.length());
565 r->setCoordinateMode(mode);
566
567 r->setSpread(pointer->spread());
568 r->setStops(pointer->stops());
569 pointer = r;
570
571 } else if (style == "bilinear") {
572 QLinearGradient *b = new QLinearGradient();
573 Q_FOREACH(QGradientStop stop, pointer->stops()) {
574 double pos = 0.5 - stop.first*0.5;
575 b->setColorAt(pos, stop.second);
576 double pos2 = 1.0 - pos;
577 if (pos != pos2) {
578 b->setColorAt(pos2, stop.second);
579 }
580 }
581 b->setCoordinateMode(mode);
582
583 b->setFinalStop(line.p2());
584 line.setAngle(180+angle);
585 b->setStart(line.p2());
586 pointer = b;
587 } else if (g) {
588 g->setFinalStop(line.p2());
589 line.setAngle(180+angle);
590 g->setStart(line.p2());
591 pointer = g;
592 }
593 }
594
595 return pointer;
596 }
static KoSegmentGradient fromXML(const QDomElement &elt)
fromXML get a segment gradient from xml.
QGradient * toQGradient() const override
reimplemented
QGradient * toQGradient() const override
reimplemented
static KoStopGradient fromXML(const QDomElement &elt)
fromXML convert a gradient from xml.

References KoSegmentGradient::fromXML(), KoStopGradient::fromXML(), KoSegmentGradient::toQGradient(), KoStopGradient::toQGradient(), and KoResource::valid.

◆ loadFromConfig()

bool psd_layer_gradient_fill::loadFromConfig ( KisFilterConfigurationSP cfg)
inline

Definition at line 390 of file psd_additional_layer_info_block.h.

390 {
391 if (cfg->name() != "gradient") {
392 return false;
393 }
394
395 bool res = bool(gradient.setContent(cfg->getString("gradient", "")));
396 dithered = cfg->getBool("dither");
397 reverse = cfg->getBool("reverse");
398 align_with_layer = false; // not supported.
399
400 style = cfg->getString("shape", "linear");
401 repeat = cfg->getString("repeat", "none");
402
403 bool polar = (cfg->getString("end_position_coordinate_system") == "polar");
404
405 QPointF start(cfg->getDouble("start_position_x", 0.0), cfg->getDouble("start_position_y", 0.0));
406 if (polar) {
407 angle = cfg->getDouble("end_position_angle", 0.0);
408 scale = cfg->getDouble("end_position_distance", 100.0);
409 } else {
410 // assume cartesian
411 QPointF end(cfg->getDouble("end_position_x", 1.0), cfg->getDouble("end_position_y", 1.0));
412 // calculate angle and scale.
413 double width = start.x() - end.x();
414 double height = start.y() - end.y();
415 angle = fmod(360.0 + kisRadiansToDegrees(atan2(width, height)), 360.0);
416 scale = sqrt((width*width) + (height*height));
417 }
418
419
420 if (style == "linear") {
421 QPointF center(imageWidth*0.5, imageHeight*0.5);
422
423 QTransform rotate;
424 rotate.rotate(angle);
425 QTransform tf = QTransform::fromTranslate(-center.x(), -center.y())
426 * rotate * QTransform::fromTranslate(center.x(), center.y());
427 QPointF topleft = tf.inverted().map(QPointF(0.0, 0.0));
428 double xPercentage = (topleft.x()/double(imageWidth)) * 100.0;
429 double yPercentage = (topleft.y()/double(imageHeight)) * 100.0;
430 offset = QPointF((start.x() - xPercentage), (start.y() - yPercentage));
431 } else {
432 scale = scale*2;
433 offset = QPointF((start.x() - 50.0), (start.y() - 50.0));
434 }
435
436 double scaleModifier = 1.0;
437 if (style == "square") {
438 scaleModifier = cos(kisDegreesToRadians(45.0));
439 double halfAngle = fmod(fabs(angle), 180.0);
440 scaleModifier *= 1/cos(kisDegreesToRadians(45.0 - fmod(halfAngle, 45.0) ));
441 if (halfAngle >= 45.0 && halfAngle < 135.0) {
442 scaleModifier = (scaleModifier) * (imageHeight / imageWidth);
443 }
444
445 angle = angle - 45.0;
446 if (angle < 0) {
447 angle = 360.0 - angle;
448 }
449
450 } else {
451 double halfAngle = fmod(fabs(angle), 180.0);
452 scaleModifier *= 1/cos(kisDegreesToRadians(halfAngle));
453 if (halfAngle >= 45.0 && halfAngle < 135.0) {
454 scaleModifier = (scaleModifier) * (imageHeight / imageWidth);
455 }
456
457 }
458
459 if (angle > 180) {
460 angle = (0.0 - fmod(angle, 180.0));
461 }
462
463 scale /= fabs(scaleModifier);
464
465
466 return res;
467 }
T kisRadiansToDegrees(T radians)
Definition kis_global.h:181
KRITAIMAGE_EXPORT qreal atan2(qreal y, qreal x)
atan2 replacement

References kisDegreesToRadians(), and kisRadiansToDegrees().

◆ setAlignWithLayer()

void psd_layer_gradient_fill::setAlignWithLayer ( bool align)
inline

Definition at line 298 of file psd_additional_layer_info_block.h.

298 {
299 align_with_layer = align;
300 }

◆ setAngle()

void psd_layer_gradient_fill::setAngle ( float Angl)
inline

Definition at line 278 of file psd_additional_layer_info_block.h.

278 {
279 angle = Angl;
280 }

◆ setDither()

void psd_layer_gradient_fill::setDither ( bool Dthr)
inline

Definition at line 270 of file psd_additional_layer_info_block.h.

270 {
271 dithered = Dthr;
272 }

◆ setFromQGradient()

void psd_layer_gradient_fill::setFromQGradient ( const QGradient * gradient)
inline

Definition at line 598 of file psd_additional_layer_info_block.h.

598 {
600 if (gradient->coordinateMode() == QGradient::ObjectBoundingMode) {
601 align_with_layer = true;
602 }
603 if (gradient->type() == QGradient::LinearGradient) {
604 const QLinearGradient *g = static_cast<const QLinearGradient*>(gradient);
605 QLineF line(g->start(), g->finalStop());
606 offset = (line.center()-QPointF(0.5, 0.5))*100.0;
607 angle = line.angle();
608 if (angle > 180) {
609 angle = (0.0 - fmod(angle, 180.0));
610 }
611 scale = (line.length())*100.0;
612 style = "linear";
613 } else {
614 const QRadialGradient *g = static_cast<const QRadialGradient*>(gradient);
615 offset = (g->center()-QPointF(0.5, 0.5)) * 100.0;
616 angle = 0;
617 scale = (g->radius()*2) * 100.0;
618 style = "radial";
619 }
620 }
static QSharedPointer< KoStopGradient > fromQGradient(const QGradient *gradient)
Creates KoStopGradient from a QGradient.
void setGradient(const KoAbstractGradientSP &newGradient)

References KoStopGradient::fromQGradient().

◆ setGradient()

void psd_layer_gradient_fill::setGradient ( const KoAbstractGradientSP & newGradient)
inline

Definition at line 253 of file psd_additional_layer_info_block.h.

253 {
254 QDomDocument document;
255 QDomElement gradientElement = document.createElement("gradient");
256 gradientElement.setAttribute("name", newGradient->name());
257
258 if (dynamic_cast<KoStopGradient*>(newGradient.data())) {
259 KoStopGradient *gradient = dynamic_cast<KoStopGradient*>(newGradient.data());
260 gradient->toXML(document, gradientElement);
261 } else if (dynamic_cast<KoSegmentGradient*>(newGradient.data())) {
262 KoSegmentGradient *gradient = dynamic_cast<KoSegmentGradient*>(newGradient.data());
263 gradient->toXML(document, gradientElement);
264 }
265
266 document.appendChild(gradientElement);
267 gradient = document;
268 }

References KoSegmentGradient::toXML(), and KoStopGradient::toXML().

◆ setOffset()

void psd_layer_gradient_fill::setOffset ( QPointF Ofst)
inline

Definition at line 306 of file psd_additional_layer_info_block.h.

306 {
307 offset = Ofst;
308 }

◆ setReverse()

void psd_layer_gradient_fill::setReverse ( bool Rvrs)
inline

Definition at line 274 of file psd_additional_layer_info_block.h.

274 {
275 reverse = Rvrs;
276 }

◆ setScale()

void psd_layer_gradient_fill::setScale ( float Scl)
inline

Definition at line 302 of file psd_additional_layer_info_block.h.

302 {
303 scale = Scl;
304 }

◆ setType()

void psd_layer_gradient_fill::setType ( const QString type)
inline

Definition at line 282 of file psd_additional_layer_info_block.h.

282 {
283 repeat = "none";
284 if (type == "Lnr "){
285 style = "linear";
286 } else if (type == "Rdl "){
287 style = "radial";
288 } else if (type == "Angl"){
289 style = "conical";
290 } else if (type == "Rflc"){
291 style = "bilinear";
292 repeat ="alternate";
293 } else {
294 style = "square"; // diamond???
295 }
296 }

◆ setupCatcher()

static void psd_layer_gradient_fill::setupCatcher ( const QString path,
KisAslCallbackObjectCatcher & catcher,
psd_layer_gradient_fill * data )
inlinestatic

Definition at line 310 of file psd_additional_layer_info_block.h.

310 {
311 catcher.subscribeGradient(path + "/Grad", std::bind(&psd_layer_gradient_fill::setGradient, data, std::placeholders::_1));
312 catcher.subscribeBoolean(path + "/Dthr", std::bind(&psd_layer_gradient_fill::setDither, data, std::placeholders::_1));
313 catcher.subscribeBoolean(path + "/Rvrs", std::bind(&psd_layer_gradient_fill::setReverse, data, std::placeholders::_1));
314 catcher.subscribeUnitFloat(path + "/Angl", "#Ang", std::bind(&psd_layer_gradient_fill::setAngle, data, std::placeholders::_1));
315 catcher.subscribeEnum(path + "/Type", "GrdT", std::bind(&psd_layer_gradient_fill::setType, data, std::placeholders::_1));
316 catcher.subscribeBoolean(path + "/Algn", std::bind(&psd_layer_gradient_fill::setAlignWithLayer, data, std::placeholders::_1));
317 catcher.subscribeUnitFloat(path + "/Scl ", "#Prc", std::bind(&psd_layer_gradient_fill::setScale, data, std::placeholders::_1));
318 catcher.subscribePoint(path + "/Ofst", std::bind(&psd_layer_gradient_fill::setOffset, data, std::placeholders::_1));
319 }
void subscribeEnum(const QString &path, const QString &typeId, ASLCallbackString callback)
void subscribeUnitFloat(const QString &path, const QString &unit, ASLCallbackDouble callback)
void subscribeGradient(const QString &path, ASLCallbackGradient callback)
void subscribePoint(const QString &path, ASLCallbackPoint callback)
void subscribeBoolean(const QString &path, ASLCallbackBoolean callback)

References setAlignWithLayer(), setAngle(), setDither(), setGradient(), setOffset(), setReverse(), setScale(), setType(), KisAslCallbackObjectCatcher::subscribeBoolean(), KisAslCallbackObjectCatcher::subscribeEnum(), KisAslCallbackObjectCatcher::subscribeGradient(), KisAslCallbackObjectCatcher::subscribePoint(), and KisAslCallbackObjectCatcher::subscribeUnitFloat().

◆ svgCompatible()

bool psd_layer_gradient_fill::svgCompatible ( )
inline

Definition at line 628 of file psd_additional_layer_info_block.h.

628 {
629 if (style == "radial" || style == "linear") {
630 return true;
631 }
632 return false;
633 }

◆ writeASL()

void psd_layer_gradient_fill::writeASL ( KisAslXmlWriter & w)
inline

Definition at line 479 of file psd_additional_layer_info_block.h.

479 {
480 if (!gradient.isNull()) {
481 const QDomElement gradientElement = gradient.firstChildElement();
482 if (!gradientElement.isNull()) {
483 const QString gradientType = gradientElement.attribute("type");
484 if (gradientType == "stop") {
485 const KoStopGradient grad = KoStopGradient::fromXML(gradientElement);
486 if (grad.valid()) {
487 w.writeStopGradient("Grad", grad);
488 }
489 } else if (gradientType == "segment") {
490 const KoSegmentGradient grad = KoSegmentGradient::fromXML(gradientElement);
491 if (grad.valid()) {
492 w.writeSegmentGradient("Grad", grad);
493 }
494 }
495 }
496 }
497 w.writeBoolean("Dthr", dithered);
498 w.writeBoolean("Rvrs", reverse);
499 w.writeUnitFloat("Angl", "#Ang", angle);
500
501 QString type = "Lnr ";
502 if (style == "linear"){
503 type = "Lnr ";
504 } else if (style == "radial") {
505 type = "Rdl ";
506 } else if (style == "conical"){
507 type = "Angl";
508 } else if (style == "bilinear"){
509 type = "Rflc";
510 } else if (style == "square") {
511 type = "Dmnd";
512 }
513
514 w.writeEnum("Type", "GrdT", type);
515 w.writeBoolean("Algn", align_with_layer);
516 w.writeUnitFloat("Scl ", "#Prc", scale);
517 w.writePoint("Ofst", offset);
518 }

References KoSegmentGradient::fromXML(), KoStopGradient::fromXML(), and KoResource::valid.

Member Data Documentation

◆ align_with_layer

bool psd_layer_gradient_fill::align_with_layer {false}

Definition at line 246 of file psd_additional_layer_info_block.h.

246{false};

◆ angle

double psd_layer_gradient_fill::angle {0.0}

Definition at line 240 of file psd_additional_layer_info_block.h.

240{0.0};

◆ dithered

bool psd_layer_gradient_fill::dithered {false}

Definition at line 245 of file psd_additional_layer_info_block.h.

245{false}; // Is gradient dithered

◆ gradient

QDomDocument psd_layer_gradient_fill::gradient

Definition at line 248 of file psd_additional_layer_info_block.h.

◆ imageHeight

int psd_layer_gradient_fill::imageHeight {1}

Definition at line 250 of file psd_additional_layer_info_block.h.

250{1};

◆ imageWidth

int psd_layer_gradient_fill::imageWidth {1}

Definition at line 249 of file psd_additional_layer_info_block.h.

249{1}; // Set when loading.

◆ offset

QPointF psd_layer_gradient_fill::offset

Definition at line 247 of file psd_additional_layer_info_block.h.

◆ repeat

QString psd_layer_gradient_fill::repeat {QString("none")}

Definition at line 242 of file psd_additional_layer_info_block.h.

242{QString("none")};

◆ reverse

bool psd_layer_gradient_fill::reverse {false}

Definition at line 244 of file psd_additional_layer_info_block.h.

244{false}; // Is gradient reverse

◆ scale

double psd_layer_gradient_fill::scale {100.0}

Definition at line 243 of file psd_additional_layer_info_block.h.

243{100.0};

◆ style

QString psd_layer_gradient_fill::style {QString("linear")}

Definition at line 241 of file psd_additional_layer_info_block.h.

241{QString("linear")};

The documentation for this struct was generated from the following file: