File indexing completed on 2025-02-02 04:22:18
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita <ashwingpdhakaita@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "MyPaintPaintOpSettings.h" 0008 0009 #include <cmath> 0010 #include <KisOptimizedBrushOutline.h> 0011 #include <MyPaintStandardOptionData.h> 0012 0013 #include <KisValueCache.h> 0014 0015 0016 struct KisMyPaintOpSettings::Private 0017 { 0018 struct Cache 0019 { 0020 qreal paintOpSize{0.0}; 0021 qreal paintOpAngle{0.0}; // the original angle value as seen by KisPaintOpSettings interface 0022 qreal offsetValue{0.0}; 0023 }; 0024 0025 struct CacheInitializer { 0026 CacheInitializer(KisMyPaintOpSettings *q) : m_q(q) {} 0027 0028 Cache initialize() { 0029 Cache value; 0030 0031 { 0032 MyPaintOffsetByRandomData data; 0033 data.read(m_q); 0034 value.offsetValue = data.strengthValue; 0035 } 0036 0037 { 0038 MyPaintRadiusLogarithmicData data; 0039 data.read(m_q); 0040 value.paintOpSize = 2 * exp(data.strengthValue); 0041 } 0042 0043 { 0044 MyPaintEllipticalDabAngleData data; 0045 data.read(m_q); 0046 value.paintOpAngle = 180.0 - data.strengthValue; 0047 } 0048 0049 return value; 0050 } 0051 0052 KisMyPaintOpSettings *m_q; 0053 }; 0054 0055 Private(KisMyPaintOpSettings *q) 0056 : cache(q) 0057 { 0058 } 0059 0060 KisValueCache<CacheInitializer> cache; 0061 }; 0062 0063 0064 KisMyPaintOpSettings::KisMyPaintOpSettings(KisResourcesInterfaceSP resourcesInterface) 0065 : KisOutlineGenerationPolicy<KisPaintOpSettings>(KisCurrentOutlineFetcher::SIZE_OPTION | 0066 KisCurrentOutlineFetcher::ROTATION_OPTION, 0067 resourcesInterface), 0068 m_d(new Private(this)) 0069 { 0070 } 0071 0072 KisMyPaintOpSettings::~KisMyPaintOpSettings() 0073 { 0074 } 0075 0076 void KisMyPaintOpSettings::setPaintOpSize(qreal value) 0077 { 0078 MyPaintRadiusLogarithmicData data; 0079 data.read(this); 0080 data.strengthValue = log(0.5 * value); 0081 data.write(this); 0082 } 0083 0084 qreal KisMyPaintOpSettings::paintOpSize() const 0085 { 0086 return m_d->cache.value().paintOpSize; 0087 } 0088 0089 void KisMyPaintOpSettings::setPaintOpAngle(qreal value) 0090 { 0091 MyPaintEllipticalDabAngleData data; 0092 data.read(this); 0093 0094 value = normalizeAngleDegrees(value); 0095 0096 if (value > 180.0) { 0097 value -= 180.0; 0098 } 0099 0100 /** 0101 * All brushes are rotated in Krita counterclockwise, 0102 * so we should invert the value for MyPaint 0103 */ 0104 value = 180.0 - value; 0105 0106 data.strengthValue = value; 0107 data.write(this); 0108 } 0109 0110 qreal KisMyPaintOpSettings::paintOpAngle() const 0111 { 0112 return m_d->cache.value().paintOpAngle; 0113 } 0114 0115 void KisMyPaintOpSettings::setPaintOpOpacity(qreal value) 0116 { 0117 MyPaintOpacityData data; 0118 data.read(this); 0119 data.strengthValue = value; 0120 data.write(this); 0121 } 0122 0123 qreal KisMyPaintOpSettings::paintOpOpacity() 0124 { 0125 MyPaintOpacityData data; 0126 data.read(this); 0127 return data.strengthValue; 0128 } 0129 0130 bool KisMyPaintOpSettings::paintIncremental() 0131 { 0132 return true; 0133 } 0134 0135 void KisMyPaintOpSettings::resetSettings(const QStringList &preserveProperties) 0136 { 0137 QStringList allKeys = preserveProperties; 0138 allKeys << MYPAINT_JSON; 0139 KisOutlineGenerationPolicy<KisPaintOpSettings>::resetSettings(allKeys); 0140 } 0141 0142 void KisMyPaintOpSettings::onPropertyChanged() 0143 { 0144 m_d->cache.clear(); 0145 KisOutlineGenerationPolicy::onPropertyChanged(); 0146 } 0147 0148 KisOptimizedBrushOutline KisMyPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom) 0149 { 0150 KisOptimizedBrushOutline path; 0151 0152 if (mode.isVisible) { 0153 qreal finalScale = 1.0; 0154 0155 const qreal offset = m_d->cache.value().offsetValue; 0156 0157 qreal radius = 0.5 * m_d->cache.value().paintOpSize; 0158 radius = radius + 2 * radius * offset; 0159 radius = qBound(3.5, radius, 500.0); 0160 0161 QPainterPath realOutline; 0162 realOutline.addEllipse(QPointF(), radius, radius); 0163 0164 path = outlineFetcher()->fetchOutline(info, this, realOutline, mode, alignForZoom, finalScale); 0165 0166 if (mode.showTiltDecoration) { 0167 QPainterPath tiltLine = makeTiltIndicator(info, 0168 realOutline.boundingRect().center(), 0169 realOutline.boundingRect().width() * 0.5, 0170 3.0); 0171 path.addPath(outlineFetcher()->fetchOutline(info, this, tiltLine, mode, alignForZoom, finalScale, 0.0, true, realOutline.boundingRect().center().x(), realOutline.boundingRect().center().y())); 0172 } 0173 } 0174 0175 return path; 0176 }