43 LinearGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd);
45 double valueAt(
double x,
double y)
const override;
48 double m_normalisedVectorX;
49 double m_normalisedVectorY;
50 double m_vectorLength;
53LinearGradientStrategy::LinearGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd)
56 double dx = gradientVectorEnd.x() - gradientVectorStart.x();
57 double dy = gradientVectorEnd.y() - gradientVectorStart.y();
59 m_vectorLength = sqrt((dx * dx) + (dy * dy));
61 if (m_vectorLength < DBL_EPSILON) {
62 m_normalisedVectorX = 0;
63 m_normalisedVectorY = 0;
65 m_normalisedVectorX = dx / m_vectorLength;
66 m_normalisedVectorY = dy / m_vectorLength;
70double LinearGradientStrategy::valueAt(
double x,
double y)
const
72 double vx =
x - m_gradientVectorStart.x();
73 double vy =
y - m_gradientVectorStart.y();
76 double t = vx * m_normalisedVectorX + vy * m_normalisedVectorY;
78 if (m_vectorLength < DBL_EPSILON) {
89class BiLinearGradientStrategy :
public LinearGradientStrategy
93 BiLinearGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd);
95 double valueAt(
double x,
double y)
const override;
98BiLinearGradientStrategy::BiLinearGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd)
99 : LinearGradientStrategy(gradientVectorStart, gradientVectorEnd)
103double BiLinearGradientStrategy::valueAt(
double x,
double y)
const
105 double t = LinearGradientStrategy::valueAt(x, y);
108 if (t < -DBL_EPSILON) {
120 RadialGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd);
122 double valueAt(
double x,
double y)
const override;
128RadialGradientStrategy::RadialGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd)
131 double dx = gradientVectorEnd.x() - gradientVectorStart.x();
132 double dy = gradientVectorEnd.y() - gradientVectorStart.y();
134 m_radius = sqrt((dx * dx) + (dy * dy));
137double RadialGradientStrategy::valueAt(
double x,
double y)
const
139 double dx =
x - m_gradientVectorStart.x();
140 double dy =
y - m_gradientVectorStart.y();
142 double distance = sqrt((dx * dx) + (dy * dy));
146 if (m_radius < DBL_EPSILON) {
160 SquareGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd);
162 double valueAt(
double x,
double y)
const override;
165 double m_normalisedVectorX;
166 double m_normalisedVectorY;
167 double m_vectorLength;
170SquareGradientStrategy::SquareGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd)
173 double dx = gradientVectorEnd.x() - gradientVectorStart.x();
174 double dy = gradientVectorEnd.y() - gradientVectorStart.y();
176 m_vectorLength = sqrt((dx * dx) + (dy * dy));
178 if (m_vectorLength < DBL_EPSILON) {
179 m_normalisedVectorX = 0;
180 m_normalisedVectorY = 0;
182 m_normalisedVectorX = dx / m_vectorLength;
183 m_normalisedVectorY = dy / m_vectorLength;
187double SquareGradientStrategy::valueAt(
double x,
double y)
const
189 double px =
x - m_gradientVectorStart.x();
190 double py =
y - m_gradientVectorStart.y();
192 double distance1 = 0;
193 double distance2 = 0;
197 if (m_vectorLength > DBL_EPSILON) {
204 distance1 = -m_normalisedVectorY * px + m_normalisedVectorX * py;
205 distance1 = fabs(distance1);
208 distance2 = -m_normalisedVectorY * -py + m_normalisedVectorX * px;
209 distance2 = fabs(distance2);
211 t = qMax(distance1, distance2) / m_vectorLength;
224 ConicalGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd);
226 double valueAt(
double x,
double y)
const override;
229 double m_vectorAngle;
232ConicalGradientStrategy::ConicalGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd)
235 double dx = gradientVectorEnd.x() - gradientVectorStart.x();
236 double dy = gradientVectorEnd.y() - gradientVectorStart.y();
242double ConicalGradientStrategy::valueAt(
double x,
double y)
const
244 double px =
x - m_gradientVectorStart.x();
245 double py =
y - m_gradientVectorStart.y();
249 angle -= m_vectorAngle;
255 double t = angle / (2 *
M_PI);
264 ConicalSymetricGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd);
266 double valueAt(
double x,
double y)
const override;
269 double m_vectorAngle;
272ConicalSymetricGradientStrategy::ConicalSymetricGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd)
275 double dx = gradientVectorEnd.x() - gradientVectorStart.x();
276 double dy = gradientVectorEnd.y() - gradientVectorStart.y();
282double ConicalSymetricGradientStrategy::valueAt(
double x,
double y)
const
284 double px =
x - m_gradientVectorStart.x();
285 double py =
y - m_gradientVectorStart.y();
289 angle -= m_vectorAngle;
309 SpiralGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd);
311 double valueAt(
double x,
double y)
const override;
314 double m_vectorAngle;
318SpiralGradientStrategy::SpiralGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd)
321 double dx = gradientVectorEnd.x() - gradientVectorStart.x();
322 double dy = gradientVectorEnd.y() - gradientVectorStart.y();
326 m_radius = sqrt((dx * dx) + (dy * dy));
329double SpiralGradientStrategy::valueAt(
double x,
double y)
const
331 double dx =
x - m_gradientVectorStart.x();
332 double dy =
y - m_gradientVectorStart.y();
334 double distance = sqrt((dx * dx) + (dy * dy));
338 angle -= m_vectorAngle;
340 if (m_radius < DBL_EPSILON) {
350 t += angle / (2 *
M_PI);
359 ReverseSpiralGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd);
361 double valueAt(
double x,
double y)
const override;
364 double m_vectorAngle;
368ReverseSpiralGradientStrategy::ReverseSpiralGradientStrategy(
const QPointF& gradientVectorStart,
const QPointF& gradientVectorEnd)
371 double dx = gradientVectorEnd.x() - gradientVectorStart.x();
372 double dy = gradientVectorEnd.y() - gradientVectorStart.y();
376 m_radius = sqrt((dx * dx) + (dy * dy));
379double ReverseSpiralGradientStrategy::valueAt(
double x,
double y)
const
381 double dx =
x - m_gradientVectorStart.x();
382 double dy =
y - m_gradientVectorStart.y();
384 double distance = sqrt((dx * dx) + (dy * dy));
388 angle -= m_vectorAngle;
390 if (m_radius < DBL_EPSILON) {
401 t += 1 - (angle / (2 *
M_PI));
407class GradientRepeatStrategy
410 GradientRepeatStrategy() {}
411 virtual ~GradientRepeatStrategy() {}
413 virtual double valueAt(
double t)
const = 0;
417class GradientRepeatNoneStrategy :
public GradientRepeatStrategy
420 static GradientRepeatNoneStrategy *
instance();
422 double valueAt(
double t)
const override;
425 GradientRepeatNoneStrategy() {}
427 static GradientRepeatNoneStrategy *m_instance;
430GradientRepeatNoneStrategy *GradientRepeatNoneStrategy::m_instance = 0;
432GradientRepeatNoneStrategy *GradientRepeatNoneStrategy::instance()
434 if (m_instance == 0) {
435 m_instance =
new GradientRepeatNoneStrategy();
436 Q_CHECK_PTR(m_instance);
443double GradientRepeatNoneStrategy::valueAt(
double t)
const
447 if (t < DBL_EPSILON) {
449 }
else if (t > 1 - DBL_EPSILON) {
457class GradientRepeatForwardsStrategy :
public GradientRepeatStrategy
460 static GradientRepeatForwardsStrategy *
instance();
462 double valueAt(
double t)
const override;
465 GradientRepeatForwardsStrategy() {}
467 static GradientRepeatForwardsStrategy *m_instance;
470GradientRepeatForwardsStrategy *GradientRepeatForwardsStrategy::m_instance = 0;
472GradientRepeatForwardsStrategy *GradientRepeatForwardsStrategy::instance()
474 if (m_instance == 0) {
475 m_instance =
new GradientRepeatForwardsStrategy();
476 Q_CHECK_PTR(m_instance);
483double GradientRepeatForwardsStrategy::valueAt(
double t)
const
485 int i =
static_cast<int>(t);
487 if (t < DBL_EPSILON) {
491 double value = t - i;
497class GradientRepeatAlternateStrategy :
public GradientRepeatStrategy
500 static GradientRepeatAlternateStrategy *
instance();
502 double valueAt(
double t)
const override;
505 GradientRepeatAlternateStrategy() {}
507 static GradientRepeatAlternateStrategy *m_instance;
510GradientRepeatAlternateStrategy *GradientRepeatAlternateStrategy::m_instance = 0;
512GradientRepeatAlternateStrategy *GradientRepeatAlternateStrategy::instance()
514 if (m_instance == 0) {
515 m_instance =
new GradientRepeatAlternateStrategy();
516 Q_CHECK_PTR(m_instance);
523double GradientRepeatAlternateStrategy::valueAt(
double t)
const
529 int i =
static_cast<int>(t);
531 double value = t - i;
540class GradientRepeatModuloDivisiveContinuousHalfStrategy :
public GradientRepeatStrategy
543 static GradientRepeatModuloDivisiveContinuousHalfStrategy *
instance();
545 double valueAt(
double t)
const override;
548 GradientRepeatModuloDivisiveContinuousHalfStrategy() {}
550 static GradientRepeatModuloDivisiveContinuousHalfStrategy *m_instance;
553GradientRepeatModuloDivisiveContinuousHalfStrategy *GradientRepeatModuloDivisiveContinuousHalfStrategy::m_instance = 0;
555GradientRepeatModuloDivisiveContinuousHalfStrategy *GradientRepeatModuloDivisiveContinuousHalfStrategy::instance()
557 if (m_instance == 0) {
558 m_instance =
new GradientRepeatModuloDivisiveContinuousHalfStrategy();
559 Q_CHECK_PTR(m_instance);
566double GradientRepeatModuloDivisiveContinuousHalfStrategy::valueAt(
double t)
const
572 int i =
static_cast<int>(t*2);
573 int ti =
static_cast<int>(t);
575 double value = t - ti;
584class RepeatForwardsPaintPolicy
589 void setup(
const QPointF& gradientVectorStart,
590 const QPointF& gradientVectorEnd,
592 const GradientRepeatStrategy *repeatStrategy,
593 qreal antiAliasThreshold,
594 bool reverseGradient,
597 const quint8 *
colorAt(qreal x, qreal y)
const;
601 qreal m_antiAliasThresholdNormalized {0};
602 qreal m_antiAliasThresholdNormalizedRev {0};
603 qreal m_antiAliasThresholdNormalizedDbl {0};
605 const GradientRepeatStrategy *m_repeatStrategy {0};
606 bool m_reverseGradient {
false};
608 const quint8 *m_extremeColors[2];
617void RepeatForwardsPaintPolicy::setup(
const QPointF& gradientVectorStart,
618 const QPointF& gradientVectorEnd,
620 const GradientRepeatStrategy *repeatStrategy,
621 qreal antiAliasThreshold,
622 bool reverseGradient,
625 qreal dx = gradientVectorEnd.x() - gradientVectorStart.x();
626 qreal dy = gradientVectorEnd.y() - gradientVectorStart.y();
627 qreal distanceInPixels = sqrt(dx * dx + dy * dy);
630 m_antiAliasThresholdNormalized = antiAliasThreshold / distanceInPixels;
631 m_antiAliasThresholdNormalizedRev = 1. - m_antiAliasThresholdNormalized;
632 m_antiAliasThresholdNormalizedDbl = 2. * m_antiAliasThresholdNormalized;
634 m_shapeStrategy = shapeStrategy;
635 m_repeatStrategy = repeatStrategy;
637 m_reverseGradient = reverseGradient;
639 m_cachedGradient = cachedGradient;
640 m_extremeColors[0] = m_cachedGradient->
cachedAt(1.);
641 m_extremeColors[1] = m_cachedGradient->
cachedAt(0.);
643 m_colorSpace = m_cachedGradient->
colorSpace();
648const quint8 *RepeatForwardsPaintPolicy::colorAt(qreal x, qreal y)
const
650 qreal t = m_shapeStrategy->valueAt(x, y);
655 if (t <= m_antiAliasThresholdNormalized &&
659 if (m_reverseGradient) {
662 return m_cachedGradient->
cachedAt(t);
665 t = m_repeatStrategy->valueAt(t);
667 if (m_reverseGradient) {
673 if (t <= m_antiAliasThresholdNormalized || t >= m_antiAliasThresholdNormalizedRev) {
675 if (t <= m_antiAliasThresholdNormalized) {
676 s = .5 + t / m_antiAliasThresholdNormalizedDbl;
678 s = (t - m_antiAliasThresholdNormalizedRev) / m_antiAliasThresholdNormalizedDbl;
681 qint16 colorWeights[2];
682 colorWeights[0] = std::lround((1.0 - s) *
qint16_MAX);
683 colorWeights[1] =
qint16_MAX - colorWeights[0];
687 return m_resultColor.data();
690 return m_cachedGradient->
cachedAt(t);
693class ConicalGradientPaintPolicy
696 void setup(
const QPointF& gradientVectorStart,
697 const QPointF& gradientVectorEnd,
699 const GradientRepeatStrategy *repeatStrategy,
700 qreal antiAliasThreshold,
701 bool reverseGradient,
704 const quint8 *
colorAt(qreal x, qreal y)
const;
707 QPointF m_gradientVectorStart;
709 const GradientRepeatStrategy *m_repeatStrategy;
710 qreal m_singularityThreshold;
711 qreal m_antiAliasThreshold;
712 bool m_reverseGradient;
714 const quint8 *m_extremeColors[2];
719void ConicalGradientPaintPolicy::setup(
const QPointF& gradientVectorStart,
720 const QPointF& gradientVectorEnd,
722 const GradientRepeatStrategy *repeatStrategy,
723 qreal antiAliasThreshold,
724 bool reverseGradient,
727 Q_UNUSED(gradientVectorEnd);
729 m_gradientVectorStart = gradientVectorStart;
731 m_shapeStrategy = shapeStrategy;
732 m_repeatStrategy = repeatStrategy;
734 m_singularityThreshold = 8.;
735 m_antiAliasThreshold = antiAliasThreshold;
737 m_reverseGradient = reverseGradient;
739 m_cachedGradient = cachedGradient;
740 m_extremeColors[0] = m_cachedGradient->
cachedAt(1.);
741 m_extremeColors[1] = m_cachedGradient->
cachedAt(0.);
743 m_colorSpace = m_cachedGradient->
colorSpace();
748const quint8 *ConicalGradientPaintPolicy::colorAt(qreal x, qreal y)
const
751 qreal dx =
x - m_gradientVectorStart.x();
752 qreal dy =
y - m_gradientVectorStart.y();
753 qreal distanceInPixels = sqrt(dx * dx + dy * dy);
755 qreal perimeter = 2. *
M_PI * distanceInPixels;
760 qreal antiAliasThresholdNormalized;
761 if (distanceInPixels < m_singularityThreshold){
762 antiAliasThresholdNormalized = distanceInPixels * m_antiAliasThreshold / m_singularityThreshold;
764 antiAliasThresholdNormalized = m_antiAliasThreshold;
766 antiAliasThresholdNormalized = antiAliasThresholdNormalized / perimeter;
767 qreal antiAliasThresholdNormalizedRev = 1. - antiAliasThresholdNormalized;
768 qreal antiAliasThresholdNormalizedDbl = 2. * antiAliasThresholdNormalized;
770 qreal t = m_shapeStrategy->valueAt(x, y);
771 t = m_repeatStrategy->valueAt(t);
773 if (m_reverseGradient) {
779 if (t <= antiAliasThresholdNormalized || t >= antiAliasThresholdNormalizedRev) {
781 if (t <= antiAliasThresholdNormalized) {
782 s = .5 + t / antiAliasThresholdNormalizedDbl;
784 s = (t - antiAliasThresholdNormalizedRev) / antiAliasThresholdNormalizedDbl;
787 qint16 colorWeights[2];
788 colorWeights[0] = std::lround((1.0 - s) *
qint16_MAX);
789 colorWeights[1] =
qint16_MAX - colorWeights[0];
793 return m_resultColor.data();
796 return m_cachedGradient->
cachedAt(t);
799class SpyralGradientRepeatNonePaintPolicy
802 SpyralGradientRepeatNonePaintPolicy(
bool isReverseSpiral =
false);
804 void setup(
const QPointF& gradientVectorStart,
805 const QPointF& gradientVectorEnd,
807 const GradientRepeatStrategy *repeatStrategy,
808 qreal antiAliasThreshold,
809 bool reverseGradient,
812 const quint8 *
colorAt(qreal x, qreal y)
const;
815 QPointF m_gradientVectorStart;
816 qreal m_distanceInPixels {0};
817 qreal m_singularityThreshold {0};
820 const GradientRepeatStrategy *m_repeatStrategy {0};
821 qreal m_antiAliasThreshold {0};
822 bool m_reverseGradient {
false};
824 mutable const quint8 *m_extremeColors[2];
827 bool m_isReverseSpiral {
false};
830SpyralGradientRepeatNonePaintPolicy::SpyralGradientRepeatNonePaintPolicy(
bool isReverseSpiral)
831 : m_isReverseSpiral(isReverseSpiral)
835void SpyralGradientRepeatNonePaintPolicy::setup(
const QPointF& gradientVectorStart,
836 const QPointF& gradientVectorEnd,
838 const GradientRepeatStrategy *repeatStrategy,
839 qreal antiAliasThreshold,
840 bool reverseGradient,
843 m_gradientVectorStart = gradientVectorStart;
845 qreal dx = gradientVectorEnd.x() - gradientVectorStart.x();
846 qreal dy = gradientVectorEnd.y() - gradientVectorStart.y();
847 m_distanceInPixels = sqrt(dx * dx + dy * dy);
848 m_singularityThreshold = m_distanceInPixels / 32.;
851 m_shapeStrategy = shapeStrategy;
852 m_repeatStrategy = repeatStrategy;
854 m_antiAliasThreshold = antiAliasThreshold;
856 m_reverseGradient = reverseGradient;
858 m_cachedGradient = cachedGradient;
860 m_colorSpace = m_cachedGradient->
colorSpace();
865const quint8 *SpyralGradientRepeatNonePaintPolicy::colorAt(qreal x, qreal y)
const
868 qreal dx =
x - m_gradientVectorStart.x();
869 qreal dy =
y - m_gradientVectorStart.y();
870 qreal distanceInPixels = sqrt(dx * dx + dy * dy);
872 qreal perimeter = 2. *
M_PI * distanceInPixels;
877 qreal antiAliasThresholdNormalized;
878 if (distanceInPixels < m_singularityThreshold) {
879 antiAliasThresholdNormalized = distanceInPixels * m_antiAliasThreshold / m_singularityThreshold;
881 antiAliasThresholdNormalized = m_antiAliasThreshold;
883 antiAliasThresholdNormalized = antiAliasThresholdNormalized / perimeter;
884 qreal antiAliasThresholdNormalizedRev = 1. - antiAliasThresholdNormalized;
885 qreal antiAliasThresholdNormalizedDbl = 2. * antiAliasThresholdNormalized;
887 qreal t = m_shapeStrategy->valueAt(x, y);
888 t = m_repeatStrategy->valueAt(t);
890 if (m_reverseGradient) {
901 angle /= (2. *
M_PI);
903 angle = m_repeatStrategy->valueAt(angle);
907 if (distanceInPixels < m_distanceInPixels && (angle <= antiAliasThresholdNormalized || angle >= antiAliasThresholdNormalizedRev)) {
909 if (angle <= antiAliasThresholdNormalized) {
910 s = .5 + angle / antiAliasThresholdNormalizedDbl;
912 s = (angle - antiAliasThresholdNormalizedRev) / antiAliasThresholdNormalizedDbl;
915 if (m_reverseGradient) {
916 distanceInPixels = m_distanceInPixels - distanceInPixels;
917 m_extremeColors[0] = m_cachedGradient->
cachedAt(0.);
919 m_extremeColors[0] = m_cachedGradient->
cachedAt(1.);
922 if (m_isReverseSpiral) {
923 m_extremeColors[1] = m_extremeColors[0];
924 m_extremeColors[0] = (m_cachedGradient->
cachedAt(distanceInPixels / m_distanceInPixels));
926 m_extremeColors[1] = (m_cachedGradient->
cachedAt(distanceInPixels / m_distanceInPixels));
929 qint16 colorWeights[2];
930 colorWeights[0] = std::lround((1.0 - s) *
qint16_MAX);
931 colorWeights[1] =
qint16_MAX - colorWeights[0];
935 return m_resultColor.data();
938 return m_cachedGradient->
cachedAt(t);
941class NoAntialiasPaintPolicy
944 void setup(
const QPointF& gradientVectorStart,
945 const QPointF& gradientVectorEnd,
947 const GradientRepeatStrategy *repeatStrategy,
948 qreal antiAliasThreshold,
949 bool reverseGradient,
952 const quint8 *
colorAt(qreal x, qreal y)
const;
956 const GradientRepeatStrategy *m_repeatStrategy {0};
957 bool m_reverseGradient {
false};
961void NoAntialiasPaintPolicy::setup(
const QPointF& gradientVectorStart,
962 const QPointF& gradientVectorEnd,
964 const GradientRepeatStrategy *repeatStrategy,
965 qreal antiAliasThreshold,
966 bool reverseGradient,
969 Q_UNUSED(gradientVectorStart);
970 Q_UNUSED(gradientVectorEnd);
971 Q_UNUSED(antiAliasThreshold);
972 m_shapeStrategy = shapeStrategy;
973 m_repeatStrategy = repeatStrategy;
974 m_reverseGradient = reverseGradient;
975 m_cachedGradient = cachedGradient;
978const quint8 *NoAntialiasPaintPolicy::colorAt(qreal x, qreal y)
const
980 qreal t = m_shapeStrategy->valueAt(x, y);
981 t = m_repeatStrategy->valueAt(t);
983 if (m_reverseGradient) {
987 return m_cachedGradient->
cachedAt(t);
999 const QRect &_processRect)
1000 : precalculatedShapeStrategy(_precalculatedShapeStrategy),
1001 processRect(_processRect) {}
1039 const qreal exponent = 2.0;
1044 boundingRect.height() >= 3);
1057 if (!
m_d->processRegions.isEmpty())
return;
1062 if (!
selection()->outlineCacheValid()) {
1076 Q_FOREACH (
const QPainterPath &subpath, splitPaths) {
1077 QRect boundingRect = subpath.boundingRect().toAlignedRect();
1079 if (boundingRect.width() < 3 || boundingRect.height() < 3) {
1085 m_d->processRegions << r;
1090 const QPointF& gradientVectorEnd,
1092 double antiAliasThreshold,
1093 bool reverseGradient,
1105 QRect(startx, starty, width, height),
1110 const QPointF& gradientVectorEnd,
1112 double antiAliasThreshold,
1113 bool reverseGradient,
1114 const QRect &applyRect,
1122 if (antiAliasThreshold > DBL_EPSILON) {
1127 RepeatForwardsPaintPolicy paintPolicy(
m_d->shape);
1138 ConicalGradientPaintPolicy paintPolicy;
1163 NoAntialiasPaintPolicy paintPolicy;
1176 const QPointF& gradientVectorEnd,
1178 double antiAliasThreshold,
1179 bool reverseGradient,
1181 const QRect &applyRect,
1186 QRect requestedRect = applyRect;
1195 switch (
m_d->shape) {
1197 Private::ProcessRegion r(
toQShared(
new LinearGradientStrategy(gradientVectorStart, gradientVectorEnd)),
1199 m_d->processRegions.clear();
1200 m_d->processRegions << r;
1204 Private::ProcessRegion r(
toQShared(
new BiLinearGradientStrategy(gradientVectorStart, gradientVectorEnd)),
1206 m_d->processRegions.clear();
1207 m_d->processRegions << r;
1211 Private::ProcessRegion r(
toQShared(
new RadialGradientStrategy(gradientVectorStart, gradientVectorEnd)),
1213 m_d->processRegions.clear();
1214 m_d->processRegions << r;
1218 Private::ProcessRegion r(
toQShared(
new SquareGradientStrategy(gradientVectorStart, gradientVectorEnd)),
1220 m_d->processRegions.clear();
1221 m_d->processRegions << r;
1225 Private::ProcessRegion r(
toQShared(
new ConicalGradientStrategy(gradientVectorStart, gradientVectorEnd)),
1227 m_d->processRegions.clear();
1228 m_d->processRegions << r;
1232 Private::ProcessRegion r(
toQShared(
new ConicalSymetricGradientStrategy(gradientVectorStart, gradientVectorEnd)),
1234 m_d->processRegions.clear();
1235 m_d->processRegions << r;
1239 Private::ProcessRegion r(
toQShared(
new SpiralGradientStrategy(gradientVectorStart, gradientVectorEnd)),
1241 m_d->processRegions.clear();
1242 m_d->processRegions << r;
1246 Private::ProcessRegion r(
toQShared(
new ReverseSpiralGradientStrategy(gradientVectorStart, gradientVectorEnd)),
1248 m_d->processRegions.clear();
1249 m_d->processRegions << r;
1258 GradientRepeatStrategy *repeatStrategy = 0;
1262 repeatStrategy = GradientRepeatNoneStrategy::instance();
1265 repeatStrategy = GradientRepeatForwardsStrategy::instance();
1269 else {repeatStrategy = GradientRepeatAlternateStrategy::instance();}
1272 Q_ASSERT(repeatStrategy != 0);
1287 const quint32 mixPixelSize = mixCs->
pixelSize();
1295 Q_FOREACH (
const Private::ProcessRegion &r,
m_d->processRegions) {
1296 QRect processRect = r.processRect;
1303 paintPolicy.setup(gradientVectorStart,
1312 const quint8 *
const pixel {paintPolicy.colorAt(it.
x(), it.
y())};
1313 memcpy(it.
rawData(), pixel, mixPixelSize);
1322 for (
int y = processRect.y(); y <= processRect.bottom(); y += rows) {
1325 for (
int x = processRect.x(); x <= processRect.right(); x += columns) {
1331 const qint32 srcRowStride = srcIt->
rowStride(x, y);
1332 const qint32 dstRowStride = dstIt->
rowStride(x, y);
1334 quint8 *dstPtr = dstIt->
rawData();
1336 op->
dither(srcPtr, srcRowStride, dstPtr, dstRowStride, x, y, columns, rows);
1341 bitBlt(requestedRect.topLeft(), dev, requestedRect);
float value(const T *src, size_t ch)
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
qreal distance(const QPointF &p1, const QPointF &p2)
PythonPluginManager * instance
virtual quint8 * rawData()=0
virtual const quint8 * rawDataConst() const =0
virtual void dither(const quint8 *src, quint8 *dst, int x, int y) const =0
KisPaintDeviceSP createCompositionSourceDevice() const
const KoColorSpace * colorSpace() const
KisDefaultBoundsBaseSP defaultBounds() const
KisRandomAccessorSP createRandomAccessorNG()
KoUpdater * progressUpdater
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
KoAbstractGradientSP gradient
virtual qint32 rowStride(qint32 x, qint32 y) const =0
virtual qint32 numContiguousRows(qint32 y) const =0
virtual void moveTo(qint32 x, qint32 y)=0
virtual qint32 numContiguousColumns(qint32 x) const =0
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE int x() const
ALWAYS_INLINE int y() const
const quint8 * cachedAt(qreal t) const
gets the color data at position 0 <= t <= 1
const KoColorSpace * colorSpace() const
virtual quint32 pixelSize() const =0
virtual const KisDitherOp * ditherOp(const QString &depth, DitherType type) const
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
KoMixColorsOp * mixColorsOp
virtual const KoColorProfile * profile() const =0
virtual void mixColors(const quint8 *const *colors, const qint16 *weights, int nColors, quint8 *dst, int weightSum=255) const =0
#define KIS_ASSERT_RECOVER_RETURN(cond)
#define KIS_ASSERT_RECOVER_NOOP(cond)
T kisGrowRect(const T &rect, U offset)
KisGradientShapeStrategy * createPolygonShapeStrategy(const QPainterPath &path, const QRect &boundingRect)
QSharedPointer< T > toQShared(T *ptr)
KRITAIMAGE_EXPORT qreal atan2(qreal y, qreal x)
atan2 replacement
KRITAFLAKE_EXPORT QColor colorAt(qreal position, const QGradientStops &stops)
Calculates color at given position from given gradient stops.
qreal KRITAIMAGE_EXPORT maxDimensionPortion(const QRectF &bounds, qreal portion, qreal minValue)
QList< QPainterPath > splitDisjointPaths(const QPainterPath &path)
QSharedPointer< KisGradientShapeStrategy > precalculatedShapeStrategy
ProcessRegion(QSharedPointer< KisGradientShapeStrategy > _precalculatedShapeStrategy, const QRect &_processRect)
@ GradientShapeReverseSpiral
@ GradientShapeConicalSymetric
@ GradientRepeatAlternate
bool paintGradient(const QPointF &gradientVectorStart, const QPointF &gradientVectorEnd, enumGradientRepeat repeat, double antiAliasThreshold, bool reverseGradient, qint32 startx, qint32 starty, qint32 width, qint32 height, bool useDithering=false)
void setGradientShape(enumGradientShape shape)
const QScopedPointer< Private > m_d
~KisGradientPainter() override
QVector< ProcessRegion > processRegions
void recalculateOutlineCache()
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.
QPainterPath outlineCache() const
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()