[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    koffice/krita/image
From:       Lukáš Tvrdý <lukast.dev () gmail ! com>
Date:       2010-10-13 18:45:37
Message-ID: 20101013184537.12D42AC895 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1185563 by lukast:

Fix brush mask generators.

o Add missing spike support to both rectangular type of masks
o Add oversampling to curve-based masks to improve quality of the mask
  (avoids artefacts when the brush mask is rotated)

 M  +1 -0      kis_base_mask_generator.cpp  
 M  +3 -0      kis_base_mask_generator.h  
 M  +4 -5      kis_circle_mask_generator.cpp  
 M  +9 -8      kis_curve_circle_mask_generator.cpp  
 M  +28 -13    kis_curve_rect_mask_generator.cpp  
 M  +20 -4     kis_rect_mask_generator.cpp  


--- trunk/koffice/krita/image/kis_base_mask_generator.cpp #1185562:1185563
@@ -37,6 +37,7 @@
     d->fv = 0.5 * fv;
     d->softness = 1.0; // by default don't change fade/softness/hardness
     d->spikes = spikes;
+    d->cachedSpikesAngle = M_PI / d->spikes;
     d->type = type;
     init();
 }
--- trunk/koffice/krita/image/kis_base_mask_generator.h #1185562:1185563
@@ -31,6 +31,8 @@
 const KoID DefaultId("default", i18n("Default")); ///< generate Krita default mask \
generator  const KoID SoftId("soft", i18n("Soft brush")); ///< generate brush mask \
from former softbrush paintop, where softness is based on curve  
+static const int OVERSAMPLING = 4;
+
 /**
  * This is the base class for mask shapes
  * You should subclass it if you want to create a new
@@ -97,6 +99,7 @@
         qreal softness;
         qreal fh, fv;
         int spikes;
+        qreal cachedSpikesAngle;
         qreal cs, ss;
         bool empty;
         Type type;
--- trunk/koffice/krita/image/kis_circle_mask_generator.cpp #1185562:1185563
@@ -28,7 +28,6 @@
 struct KisCircleMaskGenerator::Private {
     double xcoef, ycoef;
     double xfadecoef, yfadecoef;
-    double cachedSpikesAngle;
 };
 
 KisCircleMaskGenerator::KisCircleMaskGenerator(qreal diameter, qreal ratio, qreal \
fh, qreal fv, int spikes) @@ -38,7 +37,6 @@
     d->ycoef = 2.0 / (KisMaskGenerator::d->ratio * width());
     d->xfadecoef = (KisMaskGenerator::d->fh == 0) ? 1 : (1.0 / \
                (KisMaskGenerator::d->fh * width()));
     d->yfadecoef = (KisMaskGenerator::d->fv == 0) ? 1 : (1.0 / \
                (KisMaskGenerator::d->fv * KisMaskGenerator::d->ratio * width()));
-    d->cachedSpikesAngle = M_PI / KisMaskGenerator::d->spikes;
 }
 
 KisCircleMaskGenerator::~KisCircleMaskGenerator()
@@ -55,13 +53,14 @@
     if (KisMaskGenerator::d->spikes > 2) {
         double angle = (KisFastMath::atan2(yr, xr));
 
-        while (angle > d->cachedSpikesAngle ){
-            double sx = xr, sy = yr;
+        while (angle > KisMaskGenerator::d->cachedSpikesAngle ){
+            double sx = xr;
+            double sy = yr;
 
             xr = KisMaskGenerator::d->cs * sx - KisMaskGenerator::d->ss * sy;
             yr = KisMaskGenerator::d->ss * sx + KisMaskGenerator::d->cs * sy;
 
-            angle -= 2 * d->cachedSpikesAngle;
+            angle -= 2 * KisMaskGenerator::d->cachedSpikesAngle;
         }
     }
 
--- trunk/koffice/krita/image/kis_curve_circle_mask_generator.cpp #1185562:1185563
@@ -20,18 +20,19 @@
 
 #include <QDomDocument>
 #include <QVector>
+#include <QPointF>
 
 #include <KoColorSpaceConstants.h>
 
 #include "kis_fast_math.h"
 
+#include "kis_base_mask_generator.h"
 #include "kis_curve_circle_mask_generator.h"
 #include "kis_cubic_curve.h"
-#include <QPointF>
 
 struct KisCurveCircleMaskGenerator::Private {
     qreal xcoef, ycoef;
-    qreal cachedSpikesAngle;
+    qreal curveResolution;
     QVector<qreal> curveData;
     QList<QPointF> curvePoints;
     QString curve;
@@ -43,8 +44,8 @@
 {
     d->xcoef = 2.0 / width();
     d->ycoef = 2.0 / (KisMaskGenerator::d->ratio * width());
-    d->cachedSpikesAngle = M_PI / KisMaskGenerator::d->spikes;
-    d->curveData = curve.floatTransfer( width() + 2);
+    d->curveResolution = qRound( qMax(width(),height()) * OVERSAMPLING);
+    d->curveData = curve.floatTransfer( d->curveResolution + 2);
     d->curvePoints = curve.points();
     d->curve = curve.toString();
     d->dirty = false;
@@ -62,19 +63,19 @@
     if (KisMaskGenerator::d->spikes > 2) {
         double angle = (KisFastMath::atan2(yr, xr));
 
-        while (angle > d->cachedSpikesAngle ){
+        while (angle > KisMaskGenerator::d->cachedSpikesAngle ){
             double sx = xr, sy = yr;
 
             xr = KisMaskGenerator::d->cs * sx - KisMaskGenerator::d->ss * sy;
             yr = KisMaskGenerator::d->ss * sx + KisMaskGenerator::d->cs * sy;
 
-            angle -= 2 * d->cachedSpikesAngle;
+            angle -= 2 * KisMaskGenerator::d->cachedSpikesAngle;
         }
     }
 
     qreal dist = norme(xr * d->xcoef, yr * d->ycoef);
     if (dist <= 1.0){
-        qreal distance = dist * width();
+        qreal distance = dist * d->curveResolution;
     
         quint16 alphaValue = distance;
         qreal alphaValueF = distance - alphaValue;
@@ -101,7 +102,7 @@
     if (!d->dirty && softness == 1.0) return;
     d->dirty = true;
     KisMaskGenerator::setSoftness(softness);
-    KisCurveCircleMaskGenerator::transformCurveForSoftness(softness,d->curvePoints, \
width() + 2, d->curveData); +    \
KisCurveCircleMaskGenerator::transformCurveForSoftness(softness,d->curvePoints, \
d->curveResolution+2, d->curveData);  }
 
 void KisCurveCircleMaskGenerator::transformCurveForSoftness(qreal softness,const \
                QList<QPointF> &points, int curveResolution, QVector< qreal >& \
                result)
--- trunk/koffice/krita/image/kis_curve_rect_mask_generator.cpp #1185562:1185563
@@ -16,15 +16,16 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#include "kis_curve_rect_mask_generator.h"
-
 #include <cmath>
 
 #include <QDomDocument>
 #include <QVector>
-#include "kis_cubic_curve.h"
 #include <QPointF>
 
+#include <kis_fast_math.h>
+#include "kis_curve_rect_mask_generator.h"
+#include "kis_cubic_curve.h"
+
 struct KisCurveRectangleMaskGenerator::Private {
     QVector<qreal> curveData;
     QList<QPointF> curvePoints;
@@ -36,7 +37,7 @@
 KisCurveRectangleMaskGenerator::KisCurveRectangleMaskGenerator(qreal diameter, qreal \
                ratio, qreal fh, qreal fv, int spikes, const KisCubicCurve &curve)
         : KisMaskGenerator(diameter, ratio, fh, fv, spikes, RECTANGLE, SoftId), \
d(new Private)  {
-    d->curveResolution = qRound(width());
+    d->curveResolution = qRound( qMax(width(),height()) * OVERSAMPLING);
     d->curveData = curve.floatTransfer( d->curveResolution + 1); 
     d->curvePoints = curve.points();
     d->curve = curve.toString();
@@ -55,21 +56,35 @@
         return 255;
     }
 
-    double s = qAbs(x) / width();
-    if (s > 1.0){
-        return 255;
+    double xr = x;
+    double yr = qAbs(y);
+
+    if (KisMaskGenerator::d->spikes > 2) {
+        double angle = (KisFastMath::atan2(yr, xr));
+
+        while (angle > KisMaskGenerator::d->cachedSpikesAngle ){
+            double sx = xr;
+            double sy = yr;
+
+            xr = KisMaskGenerator::d->cs * sx - KisMaskGenerator::d->ss * sy;
+            yr = KisMaskGenerator::d->ss * sx + KisMaskGenerator::d->cs * sy;
+
+            angle -= 2 * KisMaskGenerator::d->cachedSpikesAngle;
     }
+    }
     
-    double t = qAbs(y) / height();
-    if (t > 1.0){
+    xr = qAbs(xr / width());
+    yr = qAbs(yr / height());
+    
+    if (xr > 1.0 || yr > 1.0){
         return 255;
     }
     
-    int sIndex = qRound(s * (d->curveResolution));
-    int tIndex = qRound(t * (d->curveResolution));
+    int sIndex = qRound(xr * (d->curveResolution));
+    int tIndex = qRound(yr * (d->curveResolution));
     
-    int sIndexInverted = width() - sIndex;
-    int tIndexInverted = width() - tIndex;
+    int sIndexInverted = d->curveResolution - sIndex;
+    int tIndexInverted = d->curveResolution - tIndex;
     
     qreal blend = (d->curveData.at(sIndex) * (1.0 - d->curveData.at(sIndexInverted)) \
                *
                   d->curveData.at(tIndex) * (1.0 - \
                d->curveData.at(tIndexInverted)));
--- trunk/koffice/krita/image/kis_rect_mask_generator.cpp #1185562:1185563
@@ -16,12 +16,15 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#include "kis_rect_mask_generator.h"
-
 #include <cmath>
 
 #include <QDomDocument>
 
+#include "kis_fast_math.h"
+
+#include "kis_rect_mask_generator.h"
+#include "kis_base_mask_generator.h"
+
 struct KisRectangleMaskGenerator::Private {
     double m_c;
     double m_halfWidth, m_halfHeight;
@@ -30,8 +33,7 @@
 KisRectangleMaskGenerator::KisRectangleMaskGenerator(qreal radius, qreal ratio, \
                qreal fh, qreal fv, int spikes)
         : KisMaskGenerator(radius, ratio, fh, fv, spikes, RECTANGLE, DefaultId), \
d(new Private)  {
-    if (KisMaskGenerator::d->fv == 0 &&
-            KisMaskGenerator::d->fh == 0) {
+    if (KisMaskGenerator::d->fv == 0 && KisMaskGenerator::d->fh == 0) {
         d->m_c = 0;
     } else {
         d->m_c = (KisMaskGenerator::d->fv / KisMaskGenerator::d->fh);
@@ -55,6 +57,20 @@
     double xr = qAbs(x /*- m_xcenter*/) / width();
     double yr = qAbs(y /*- m_ycenter*/) / height();
     
+    if (KisMaskGenerator::d->spikes > 2) {
+        double angle = (KisFastMath::atan2(yr, xr));
+
+        while (angle > KisMaskGenerator::d->cachedSpikesAngle ){
+            double sx = xr;
+            double sy = yr;
+
+            xr = KisMaskGenerator::d->cs * sx - KisMaskGenerator::d->ss * sy;
+            yr = KisMaskGenerator::d->ss * sx + KisMaskGenerator::d->cs * sy;
+
+            angle -= 2 * KisMaskGenerator::d->cachedSpikesAngle;
+        }
+    }
+
     qreal fhTransformed = KisMaskGenerator::d->fh * softness();
     qreal fvTransformed = KisMaskGenerator::d->fv * softness();
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic