kis_circle_mask_generator.cpp 4.14 KB
Newer Older
1 2
/*
 *  Copyright (c) 2004,2007-2009 Cyrille Berger <cberger@cberger.net>
3
 *  Copyright (c) 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
4
 *  Copyright (c) 2012 Sven Langkamp <sven.langkamp@gmail.com>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

21
#include <cmath>
22

Yuri Chornoivan's avatar
Yuri Chornoivan committed
23
#include <config-vc.h>
24
#ifdef HAVE_VC
25
#if defined(__clang__)
Boudewijn Rempt's avatar
Boudewijn Rempt committed
26 27
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic ignored "-Wlocal-type-template-args"
28
#endif
29 30 31 32 33 34
#if defined _MSC_VER
// Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false'
#pragma warning ( push )
#pragma warning ( disable : 4244 )
#pragma warning ( disable : 4800 )
#endif
35 36
#include <Vc/Vc>
#include <Vc/IO>
37 38 39
#if defined _MSC_VER
#pragma warning ( pop )
#endif
40
#endif
41 42 43

#include <QDomDocument>

44 45
#include "kis_fast_math.h"
#include "kis_circle_mask_generator.h"
46
#include "kis_circle_mask_generator_p.h"
47
#include "kis_base_mask_generator.h"
48
#include "kis_brush_mask_applicator_factories.h"
49
#include "kis_brush_mask_applicator_base.h"
50

51

52 53
KisCircleMaskGenerator::KisCircleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges)
    : KisMaskGenerator(diameter, ratio, fh, fv, spikes, antialiasEdges, CIRCLE, DefaultId), d(new Private)
54
{
55
    setScale(1.0, 1.0);
56

57 58 59
    // store the variable locally to allow vector implementation read it easily
    d->copyOfAntialiasEdges = antialiasEdges;

60
    d->applicator = createOptimizedClass<MaskApplicatorFactory<KisCircleMaskGenerator, KisBrushMaskVectorApplicator> >(this);
61 62
}

63 64 65 66 67 68
void KisCircleMaskGenerator::setScale(qreal scaleX, qreal scaleY)
{
    KisMaskGenerator::setScale(scaleX, scaleY);

    d->xcoef = 2.0 / effectiveSrcWidth();
    d->ycoef = 2.0 / effectiveSrcHeight();
69 70 71 72
    d->xfadecoef = (horizontalFade() == 0) ? 1 : (2.0 / (horizontalFade() * effectiveSrcWidth()));
    d->yfadecoef = (verticalFade() == 0)   ? 1 : (2.0 / (verticalFade() * effectiveSrcHeight()));
    d->transformedFadeX = KisMaskGenerator::softness() * d->xfadecoef;
    d->transformedFadeY = KisMaskGenerator::softness() * d->yfadecoef;
73 74 75 76

    d->noFading = !d->copyOfAntialiasEdges &&
        qFuzzyCompare(d->xcoef, d->transformedFadeX) &&
        qFuzzyCompare(d->ycoef, d->transformedFadeY);
77 78
}

79 80
KisCircleMaskGenerator::~KisCircleMaskGenerator()
{
81
    delete d->applicator;
82 83 84
    delete d;
}

85 86
bool KisCircleMaskGenerator::shouldSupersample() const
{
87
    return effectiveSrcWidth() < 10 || effectiveSrcHeight() < 10;
88 89
}

90 91
bool KisCircleMaskGenerator::shouldVectorize() const
{
92
    return !shouldSupersample() && spikes() == 2;
93 94
}

95 96 97 98
KisBrushMaskApplicatorBase* KisCircleMaskGenerator::applicator()
{
    return d->applicator;
}
99

100
quint8 KisCircleMaskGenerator::valueAt(qreal x, qreal y) const
101
{
102 103 104 105
    if (isEmpty()) return 255;
    qreal xr = (x /*- m_xcenter*/);
    qreal yr = qAbs(y /*- m_ycenter*/);
    fixRotation(xr, yr);
106

107 108 109 110
    qreal n = norme(xr * d->xcoef, yr * d->ycoef);
    if (n > 1.0) return 255;

    // we add +1.0 to ensure correct antialising on the border
111
    if (antialiasEdges()) {
112 113 114 115 116 117
        xr = qAbs(xr) + 1.0;
        yr = qAbs(yr) + 1.0;
    }

    qreal nf = norme(xr * d->transformedFadeX,
                     yr * d->transformedFadeY);
118 119 120

    if (nf < 1.0) return 0;
    return 255 * n * (nf - 1.0) / (nf - n);
121 122
}

123 124
void KisCircleMaskGenerator::setSoftness(qreal softness)
{
125
    KisMaskGenerator::setSoftness(softness);
126
    qreal safeSoftnessCoeff = qreal(1.0) / qMax(qreal(0.01), softness);
127

Dmitry Kazakov's avatar
Dmitry Kazakov committed
128 129
    d->transformedFadeX = d->xfadecoef * safeSoftnessCoeff;
    d->transformedFadeY = d->yfadecoef * safeSoftnessCoeff;
130
}