예제 #1
0
void HairyBrush::saturationDepletion(Bristle * bristle, KoColor &bristleColor, qreal pressure, qreal inkDeplation)
{
    qreal saturation;
    if (m_properties->useWeights) {
        // new weighted way (experiment)
        saturation = (
                         (pressure * m_properties->pressureWeight) +
                         (bristle->length() * m_properties->bristleLengthWeight) +
                         (bristle->inkAmount() * m_properties->bristleInkAmountWeight) +
                         ((1.0 - inkDeplation) * m_properties->inkDepletionWeight)) - 1.0;
    }
    else {
        // old way of computing saturation
        saturation = (
                         pressure *
                         bristle->length() *
                         bristle->inkAmount() *
                         (1.0 - inkDeplation)) - 1.0;

    }
	m_transfo->setParameter(m_transfo->parameterId("h"), 0.0);
	m_transfo->setParameter(m_transfo->parameterId("v"), 0.0);
    m_transfo->setParameter(m_saturationId, saturation);
	m_transfo->setParameter(3, 1);//sets the type to
	m_transfo->setParameter(4, false);//sets the colorize to none.
    m_transfo->transform(bristleColor.data(), bristleColor.data() , 1);
}
예제 #2
0
void IndexColorPalette::insertShades(KoColor koclrA, KoColor koclrB, int shades)
{
    koclrA.convertTo(KoColorSpaceRegistry::instance()->lab16());
    koclrB.convertTo(KoColorSpaceRegistry::instance()->lab16());
    LabColor clrA = *(reinterpret_cast<LabColor*>(koclrA.data()));
    LabColor clrB = *(reinterpret_cast<LabColor*>(koclrB.data()));
    insertShades(clrA, clrB, shades);
}
예제 #3
0
void TestKoColor::testForModel(QString model)
{
    QColor qc(200, 125, 100);
    QList<KoID> depthIDs = KoColorSpaceRegistry::instance()->colorDepthList(model, KoColorSpaceRegistry::AllColorSpaces);
    foreach(const KoID& depthId, depthIDs) {
        const KoColorSpace* cs = KoColorSpaceRegistry::instance()->colorSpace(model, depthId.id() , "");
        if (cs) {
            KoColor kc(cs);
            kc.fromQColor(qc);
            QDomDocument doc;
            QDomElement elt = doc.createElement("color");
            kc.toXML(doc, elt);
            doc.appendChild(elt);
            dbgPigment << doc.toString();
            KoColor kcu = KoColor::fromXML(elt.firstChildElement(), depthId.id(), QHash<QString, QString>());
            QVERIFY2(*(kc.colorSpace()) == *(kcu.colorSpace()),
                     QString("Not identical color space (colorModelId = %1 depthId = %2) != (colorModelId = %3 depthId = %4) ")
                     .arg(kc.colorSpace()->colorModelId().id())
                     .arg(kc.colorSpace()->colorDepthId().id())
                     .arg(kcu.colorSpace()->colorModelId().id())
                     .arg(kcu.colorSpace()->colorDepthId().id()).toLatin1());
            QVERIFY(cs->difference(kcu.data(), kc.data()) <= 1);
        }
    }

}
예제 #4
0
inline void HairyBrush::darkenPixel(int wx, int wy, const KoColor &color)
{
    m_dabAccessor->moveTo(wx, wy);
    if (m_dab->colorSpace()->opacityU8(m_dabAccessor->rawData()) < color.opacityU8()) {
        memcpy(m_dabAccessor->rawData(), color.data(), m_pixelSize);
    }
}
예제 #5
0
void HairyBrush::paintParticle(QPointF pos, const KoColor& color)
{
    // opacity top left, right, bottom left, right
    memcpy(m_color.data(), color.data(), m_pixelSize);
    quint8 opacity = color.opacityU8();

    int ipx = int (pos.x());
    int ipy = int (pos.y());
    qreal fx = pos.x() - ipx;
    qreal fy = pos.y() - ipy;

    quint8 btl = qRound((1.0 - fx) * (1.0 - fy) * opacity);
    quint8 btr = qRound((fx)  * (1.0 - fy) * opacity);
    quint8 bbl = qRound((1.0 - fx) * (fy)  * opacity);
    quint8 bbr = qRound((fx)  * (fy)  * opacity);

    m_color.setOpacity(btl);
    plotPixel(ipx  , ipy, m_color);

    m_color.setOpacity(btr);
    plotPixel(ipx + 1  , ipy, m_color);

    m_color.setOpacity(bbl);
    plotPixel(ipx  , ipy + 1, m_color);

    m_color.setOpacity(bbr);
    plotPixel(ipx + 1 , ipy + 1, m_color);
}
예제 #6
0
QImage KisVisualColorSelectorShape::getImageMap()
{
    //qDebug() << this  << ">>>>>>>>> getImageMap()" << m_d->imagesNeedUpdate;

    if (m_d->imagesNeedUpdate == true) {
        m_d->gradient = QImage(width(), height(), QImage::Format_ARGB32);
        m_d->gradient.fill(Qt::transparent);
//        KoColor c = m_d->currentColor;

        // Fill a buffer with the right kocolors
        quint8 *data = new quint8[width() * height() * height()];
        quint8 *dataPtr = data;
        for (int y = 0; y < m_d->gradient.height(); y++) {
            for (int x=0; x < m_d->gradient.width(); x++) {
                QPointF newcoordinate = convertWidgetCoordinateToShapeCoordinate(QPoint(x, y));
                KoColor c = convertShapeCoordinateToKoColor(newcoordinate);
                memcpy(dataPtr, c.data(), m_d->currentColor.colorSpace()->pixelSize());
                dataPtr += m_d->currentColor.colorSpace()->pixelSize();
            }
        }
        // Convert the buffer to a qimage
        if (m_d->displayRenderer) {
            m_d->gradient = m_d->displayRenderer->convertToQImage(m_d->currentColor.colorSpace(), data, width(), height());
        }
        else {
            m_d->gradient = m_d->currentColor.colorSpace()->convertToQImage(data, width(), height(), 0, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
        }
        delete[] data;

        m_d->imagesNeedUpdate = false;
    }
    return m_d->gradient;
}
예제 #7
0
void SprayBrush::paintDistanceMap(KisPaintDeviceSP dev, const KisPaintInformation &info, const KoColor &painterColor){
    KisRandomAccessor accessor = dev->createRandomAccessor(0, 0);
    KoColor color = painterColor;

    qreal posX = info.pos().x();
    qreal posY = info.pos().y();
    
    qreal opacity = 255;
    for (int y = -m_radius; y <= m_radius; y++){
        for (int x = -m_radius; x <= m_radius; x++){
            //opacity = sqrt(y*y + x*x) / m_radius;
            opacity = (y*y + x*x) / (m_radius * m_radius);
            opacity = 1.0 - opacity;
            opacity *= m_scale;

            if (opacity < 0) continue;
            if (opacity > 1.0) opacity = 1.0;

            if ( (y*y + x*x) <= (m_radius * m_radius) )
            {
                color.setOpacity( opacity * 255);
                accessor.moveTo(x + posX, y + posY);
                memcpy( accessor.rawData(), color.data(), dev->colorSpace()->pixelSize() );
            }

        }
    }
}
예제 #8
0
void IndexColorPalette::insertColor(QColor qclr)
{
    KoColor koclr;
    koclr.fromQColor(qclr);
    koclr.convertTo(KoColorSpaceRegistry::instance()->lab16());
    LabColor clr = *(reinterpret_cast<LabColor*>(koclr.data()));
    insertColor(clr);
}
예제 #9
0
void HairyBrush::paintParticle(QPointF pos, const KoColor& color, qreal weight)
{
    // opacity top left, right, bottom left, right
    quint8 opacity = color.opacityU8();
    opacity *= weight;

    int ipx = int (pos.x());
    int ipy = int (pos.y());
    qreal fx = pos.x() - ipx;
    qreal fy = pos.y() - ipy;

    quint8 btl = qRound((1.0 - fx) * (1.0 - fy) * opacity);
    quint8 btr = qRound((fx)  * (1.0 - fy) * opacity);
    quint8 bbl = qRound((1.0 - fx) * (fy)  * opacity);
    quint8 bbr = qRound((fx)  * (fy)  * opacity);

    const KoColorSpace * cs = m_dab->colorSpace();

    m_dabAccessor->moveTo(ipx  , ipy);
    btl = quint8(qBound<quint16>(OPACITY_TRANSPARENT_U8, btl + cs->opacityU8(m_dabAccessor->rawData()), OPACITY_OPAQUE_U8));
    memcpy(m_dabAccessor->rawData(), color.data(), cs->pixelSize());
    cs->setOpacity(m_dabAccessor->rawData(), btl, 1);

    m_dabAccessor->moveTo(ipx + 1, ipy);
    btr =  quint8(qBound<quint16>(OPACITY_TRANSPARENT_U8, btr + cs->opacityU8(m_dabAccessor->rawData()), OPACITY_OPAQUE_U8));
    memcpy(m_dabAccessor->rawData(), color.data(), cs->pixelSize());
    cs->setOpacity(m_dabAccessor->rawData(), btr, 1);

    m_dabAccessor->moveTo(ipx, ipy + 1);
    bbl = quint8(qBound<quint16>(OPACITY_TRANSPARENT_U8, bbl + cs->opacityU8(m_dabAccessor->rawData()), OPACITY_OPAQUE_U8));
    memcpy(m_dabAccessor->rawData(), color.data(), cs->pixelSize());
    cs->setOpacity(m_dabAccessor->rawData(), bbl, 1);

    m_dabAccessor->moveTo(ipx + 1, ipy + 1);
    bbr = quint8(qBound<quint16>(OPACITY_TRANSPARENT_U8, bbr + cs->opacityU8(m_dabAccessor->rawData()), OPACITY_OPAQUE_U8));
    memcpy(m_dabAccessor->rawData(), color.data(), cs->pixelSize());
    cs->setOpacity(m_dabAccessor->rawData(), bbr, 1);
}
예제 #10
0
void CurveBrush::putPixel(QPointF pos, KoColor &color)
{
    int ipx = int (pos.x());
    int ipy = int (pos.y());
    qreal fx = pos.x() - ipx;
    qreal fy = pos.y() - ipy;

    qreal btl = (1 - fx) * (1 - fy);
    qreal btr = (fx)   * (1 - fy);
    qreal bbl = (1 - fx) * (fy);
    qreal bbr = (fx)   * (fy);

    color.setOpacity(btl);
    m_writeAccessor->moveTo(ipx  , ipy);
    if (cs->opacityU8(m_writeAccessor->rawData()) < color.opacityU8()) {
        memcpy(m_writeAccessor->rawData(), color.data(), m_pixelSize);
    }

    color.setOpacity(btr);
    m_writeAccessor->moveTo(ipx + 1, ipy);
    if (cs->opacityU8(m_writeAccessor->rawData()) < color.opacityU8()) {
        memcpy(m_writeAccessor->rawData(), color.data(), m_pixelSize);
    }

    color.setOpacity(bbl);
    m_writeAccessor->moveTo(ipx, ipy + 1);
    if (cs->opacityU8(m_writeAccessor->rawData()) < color.opacityU8()) {
        memcpy(m_writeAccessor->rawData(), color.data(), m_pixelSize);
    }

    color.setOpacity(bbr);
    m_writeAccessor->moveTo(ipx + 1, ipy + 1);
    if (cs->opacityU8(m_writeAccessor->rawData()) < color.opacityU8()) {
        memcpy(m_writeAccessor->rawData(), color.data(), m_pixelSize);
    }
}
예제 #11
0
void KisVisualColorSelectorShape::mouseMoveEvent(QMouseEvent *e)
{
    if (m_d->mousePressActive==true && this->mask().contains(e->pos())) {
        QPointF coordinates = convertWidgetCoordinateToShapeCoordinate(e->pos());
        quint8* oldData = m_d->currentColor.data();
        KoColor col = convertShapeCoordinateToKoColor(coordinates, true);
        QRect offsetrect(this->geometry().topLeft()+QPoint(7.0,7.0), this->geometry().bottomRight()-QPoint(7.0,7.0));
        if (offsetrect.contains(e->pos()) || (m_d->colorSpace->difference(col.data(), oldData)>5)) {
            setColor(col);
            if (!m_d->updateTimer->isActive()) {
                Q_EMIT sigNewColor(col);
                m_d->updateTimer->start();
            }
        }

    } else {
        e->ignore();
    }
}
예제 #12
0
void KoXYColorSelector::drawContents( QPainter *painter )
{
    KoColor c = m_colors[0]; // quick way to set the colorspace
    QColor color;

    const quint8 *colors[4];
    colors[0] = m_colors[0].data();
    colors[1] = m_colors[1].data();
    colors[2] = m_colors[2].data();
    colors[3] = m_colors[3].data();

    QRect contentsRect_(contentsRect());
    QImage image(contentsRect_.width(), contentsRect_.height(), QImage::Format_ARGB32 );
    KoMixColorsOp * mixOp = m_colorSpace->mixColorsOp();

    for (int x = 0; x < contentsRect_.width(); x++)
        for (int y = 0; y < contentsRect_.height(); y++){

            qreal xVal = static_cast<qreal>(x) / (contentsRect_.width() - 1);
            qreal yVal = static_cast<qreal>(y) / (contentsRect_.height() - 1);

            qint16 colorWeights[4];
            colorWeights[0] = static_cast<quint8>((1.0 - yVal) * (1.0 - xVal) * 255 + 0.5);
            colorWeights[1] = static_cast<quint8>((1.0 - yVal) * (xVal) * 255 + 0.5);
            colorWeights[2] = static_cast<quint8>((yVal) * (1.0 - xVal) * 255 + 0.5);
            colorWeights[3] = static_cast<quint8>((yVal) * (xVal) * 255 + 0.5);

            mixOp->mixColors(colors, colorWeights, 4, c.data());

            c.toQColor( &color);

            image.setPixel(x, y, color.rgba());
        }

    painter->drawImage( contentsRect_, image, QRect( 0, 0, image.width(), image.height()) );
}
예제 #13
0
QPointF KisVisualColorSelectorShape::convertKoColorToShapeCoordinate(KoColor c)
{
    ////qDebug() << this  << ">>>>>>>>> convertKoColorToShapeCoordinate()";

    if (c.colorSpace() != m_d->colorSpace) {
        c.convertTo(m_d->colorSpace);
    }
    QVector <float> channelValues (m_d->currentColor.colorSpace()->channelCount());
    channelValues.fill(1.0);
    m_d->colorSpace->normalisedChannelsValue(c.data(), channelValues);
    QVector <float> channelValuesDisplay = channelValues;
    QVector <qreal> maxvalue(c.colorSpace()->channelCount());
    maxvalue.fill(1.0);
    if (m_d->displayRenderer
            && (m_d->colorSpace->colorDepthId() == Float16BitsColorDepthID
                || m_d->colorSpace->colorDepthId() == Float32BitsColorDepthID
                || m_d->colorSpace->colorDepthId() == Float64BitsColorDepthID)
            && m_d->colorSpace->colorModelId() != LABAColorModelID
            && m_d->colorSpace->colorModelId() != CMYKAColorModelID) {
        for (int ch = 0; ch<maxvalue.size(); ch++) {
            KoChannelInfo *channel = m_d->colorSpace->channels()[ch];
            maxvalue[ch] = m_d->displayRenderer->maxVisibleFloatValue(channel);
            channelValues[ch] = channelValues[ch]/(maxvalue[ch]);
            channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(ch, m_d->colorSpace->channels())] = channelValues[ch];
        }
    } else {
        for (int i =0; i<channelValues.size();i++) {
            channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(i, m_d->colorSpace->channels())] = qBound((float)0.0,channelValues[i], (float)1.0);
        }
    }
    QPointF coordinates(0.0,0.0);
    qreal huedivider = 1.0;
    qreal huedivider2 = 1.0;
    if (m_d->channel1==0) {
        huedivider = 360.0;
    }
    if (m_d->channel2==0) {
        huedivider2 = 360.0;
    }
    if (m_d->model != ColorModel::Channel && c.colorSpace()->colorModelId().id() == "RGBA") {
        if (c.colorSpace()->colorModelId().id() == "RGBA") {
            if (m_d->model == ColorModel::HSV){
                QVector <float> inbetween(3);
                RGBToHSV(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]);
                inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween)));
                coordinates.setX(inbetween[m_d->channel1]/huedivider);
                if (m_d->dimension == Dimensions::twodimensional) {
                    coordinates.setY(inbetween[m_d->channel2]/huedivider2);
                }
            } else if (m_d->model == ColorModel::HSL) {
                QVector <float> inbetween(3);
                RGBToHSL(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]);
                inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween)));
                coordinates.setX(inbetween[m_d->channel1]/huedivider);
                if (m_d->dimension == Dimensions::twodimensional) {
                    coordinates.setY(inbetween[m_d->channel2]/huedivider2);
                }
            } else if (m_d->model == ColorModel::HSI) {
                QVector <qreal> chan2 = convertvectorfloatToqreal(channelValuesDisplay);
                QVector <qreal> inbetween(3);
                RGBToHSI(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]);
                inbetween = getHSX(inbetween);
                coordinates.setX(inbetween[m_d->channel1]);
                if (m_d->dimension == Dimensions::twodimensional) {
                    coordinates.setY(inbetween[m_d->channel2]);
                }
            } else if (m_d->model == ColorModel::HSY) {
                QVector <qreal> luma = m_d->colorSpace->lumaCoefficients();
                QVector <qreal> chan2 = convertvectorfloatToqreal(channelValuesDisplay);
                QVector <qreal> inbetween(3);
                RGBToHSY(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2], luma[0], luma[1], luma[2]);
                inbetween = getHSX(inbetween);
                coordinates.setX(inbetween[m_d->channel1]);
                if (m_d->dimension == Dimensions::twodimensional) {
                    coordinates.setY(inbetween[m_d->channel2]);
                }
            }
        }
    } else {
        coordinates.setX(qBound((float)0.0, channelValuesDisplay[m_d->channel1], (float)1.0));
        if (m_d->dimension == Dimensions::twodimensional) {
            coordinates.setY(qBound((float)0.0, channelValuesDisplay[m_d->channel2], (float)1.0));
        }
    }
    return coordinates;
}
예제 #14
0
KoColor KisVisualColorSelectorShape::convertShapeCoordinateToKoColor(QPointF coordinates, bool cursor)
{
    //qDebug() << this  << ">>>>>>>>> convertShapeCoordinateToKoColor()" << coordinates;

    KoColor c = m_d->currentColor;
    QVector <float> channelValues (c.colorSpace()->channelCount());
    channelValues.fill(1.0);
    c.colorSpace()->normalisedChannelsValue(c.data(), channelValues);
    QVector <float> channelValuesDisplay = channelValues;
    QVector <qreal> maxvalue(c.colorSpace()->channelCount());
    maxvalue.fill(1.0);

    if (m_d->displayRenderer
            && (m_d->colorSpace->colorDepthId() == Float16BitsColorDepthID
                || m_d->colorSpace->colorDepthId() == Float32BitsColorDepthID
                || m_d->colorSpace->colorDepthId() == Float64BitsColorDepthID)
            && m_d->colorSpace->colorModelId() != LABAColorModelID
            && m_d->colorSpace->colorModelId() != CMYKAColorModelID) {

        for (int ch = 0; ch < maxvalue.size(); ch++) {
            KoChannelInfo *channel = m_d->colorSpace->channels()[ch];
            maxvalue[ch] = m_d->displayRenderer->maxVisibleFloatValue(channel);
            channelValues[ch] = channelValues[ch]/(maxvalue[ch]);
            channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(ch, m_d->colorSpace->channels())] = channelValues[ch];
        }
    }
    else {
        for (int i =0; i < channelValues.size();i++) {
            channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(i, m_d->colorSpace->channels())] = qBound((float)0.0,channelValues[i], (float)1.0);
        }
    }

    qreal huedivider = 1.0;
    qreal huedivider2 = 1.0;

    if (m_d->channel1 == 0) {
        huedivider = 360.0;
    }

    if (m_d->channel2 == 0) {
        huedivider2 = 360.0;
    }

    if (m_d->model != ColorModel::Channel && c.colorSpace()->colorModelId().id() == "RGBA") {

        if (m_d->model == ColorModel::HSV) {
            /*
             * RGBToHSV has a undefined hue possibility. This means that hue will be -1.
             * This can be annoying for dealing with a selector, but I understand it is being
             * used for the KoColorSelector... For now implement a qMax here.
             */
            QVector <float> inbetween(3);
            RGBToHSV(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]);
            inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween)));
            inbetween[m_d->channel1] = coordinates.x()*huedivider;
            if (m_d->dimension == Dimensions::twodimensional) {
                inbetween[m_d->channel2] = coordinates.y()*huedivider2;
            }
            if (cursor) {
                setHSX(convertvectorfloatToqreal(inbetween));
                Q_EMIT sigHSXchange();
            }
            HSVToRGB(qMax(inbetween[0],(float)0.0), inbetween[1], inbetween[2], &channelValuesDisplay[0], &channelValuesDisplay[1], &channelValuesDisplay[2]);
        }
        else if (m_d->model == ColorModel::HSL) {
            /*
             * HSLToRGB can give negative values on the grey. I fixed the fromNormalisedChannel function to clamp,
             * but you might want to manually clamp for floating point values.
             */
            QVector <float> inbetween(3);
            RGBToHSL(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]);
            inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween)));
            inbetween[m_d->channel1] = fmod(coordinates.x()*huedivider, 360.0);
            if (m_d->dimension == Dimensions::twodimensional) {
                inbetween[m_d->channel2] = coordinates.y()*huedivider2;
            }
            if (cursor) {
                setHSX(convertvectorfloatToqreal(inbetween));
                Q_EMIT sigHSXchange();
            }
            HSLToRGB(qMax(inbetween[0], (float)0.0), inbetween[1], inbetween[2], &channelValuesDisplay[0], &channelValuesDisplay[1], &channelValuesDisplay[2]);
        }
        else if (m_d->model == ColorModel::HSI) {
            /*
             * HSI is a modified HSY function.
             */
            QVector <qreal> chan2 = convertvectorfloatToqreal(channelValuesDisplay);
            QVector <qreal> inbetween(3);
            RGBToHSI(chan2[0],chan2[1], chan2[2], &inbetween[0], &inbetween[1], &inbetween[2]);
            inbetween = getHSX(inbetween);
            inbetween[m_d->channel1] = coordinates.x();
            if (m_d->dimension == Dimensions::twodimensional) {
                inbetween[m_d->channel2] = coordinates.y();
            }
            if (cursor) {
                setHSX(inbetween);
                Q_EMIT sigHSXchange();
            }
            HSIToRGB(inbetween[0], inbetween[1], inbetween[2],&chan2[0],&chan2[1], &chan2[2]);
            channelValuesDisplay = convertvectorqrealTofloat(chan2);
        }
        else /*if (m_d->model == ColorModel::HSY)*/ {
            /*
             * HSY is pretty slow to render due being a pretty over-the-top function.
             * Might be worth investigating whether HCY can be used instead, but I have had
             * some weird results with that.
             */
            QVector <qreal> luma= m_d->colorSpace->lumaCoefficients();
            QVector <qreal> chan2 = convertvectorfloatToqreal(channelValuesDisplay);
            QVector <qreal> inbetween(3);
            RGBToHSY(chan2[0],chan2[1], chan2[2], &inbetween[0], &inbetween[1], &inbetween[2],
                    luma[0], luma[1], luma[2]);
            inbetween = getHSX(inbetween);
            inbetween[m_d->channel1] = coordinates.x();
            if (m_d->dimension == Dimensions::twodimensional) {
                inbetween[m_d->channel2] = coordinates.y();
            }
            if (cursor) {
                setHSX(inbetween);
                Q_EMIT sigHSXchange();
            }
            HSYToRGB(inbetween[0], inbetween[1], inbetween[2],&chan2[0],&chan2[1], &chan2[2],
                    luma[0], luma[1], luma[2]);
            channelValuesDisplay = convertvectorqrealTofloat(chan2);
        }

    }
    else {
        channelValuesDisplay[m_d->channel1] = coordinates.x();
        if (m_d->dimension == Dimensions::twodimensional) {
            channelValuesDisplay[m_d->channel2] = coordinates.y();
        }
    }

    for (int i=0; i<channelValues.size();i++) {
        channelValues[i] = channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(i, m_d->colorSpace->channels())]*(maxvalue[i]);
    }

    c.colorSpace()->fromNormalisedChannelsValue(c.data(), channelValues);

    return c;
}
void KisSmudgeRadiusOption::apply(KisPainter& painter, const KisPaintInformation& info, qreal scale, qreal posx, qreal posy,KisPaintDeviceSP dev) const
{
    double sliderValue = computeValue(info);
    int smudgeRadius = ((sliderValue * scale)*0.5)/100.0;//scale is diameter?


    KoColor color = painter.paintColor();
    if (smudgeRadius == 1) {
        dev->pixel(posx, posy, &color);
        painter.setPaintColor(color);
    } else {

        const KoColorSpace* cs = dev->colorSpace();
        int pixelSize = cs->pixelSize();

        quint8* data = new quint8[pixelSize];
        static quint8** pixels = new quint8*[2];
        qint16* weights = new qint16[2];

        pixels[1] = new quint8[pixelSize];
        pixels[0] = new quint8[pixelSize];

        int loop_increment = 1;
        if(smudgeRadius >= 8)
        {
            loop_increment = (2*smudgeRadius)/16;
        }
        int i = 0;
        int k = 0;
        int j = 0;
        KisRandomConstAccessorSP accessor = dev->createRandomConstAccessorNG(0, 0);
        KisCrossDeviceColorPickerInt colorPicker(painter.device(), color);
        colorPicker.pickColor(posx, posy, color.data());

        for (int y = 0; y <= smudgeRadius; y = y + loop_increment) {
            for (int x = 0; x <= smudgeRadius; x = x + loop_increment) {

                for(j = 0;j < 2;j++)
                {
                    if(j == 1)
                    {
                        y = y*(-1);
                    }
                    for(k = 0;k < 2;k++)
                    {
                        if(k == 1)
                        {
                            x = x*(-1);
                        }
                        accessor->moveTo(posx + x, posy + y);
                        memcpy(pixels[1], accessor->rawDataConst(), pixelSize);
                        if(i == 0)
                        {
                            memcpy(pixels[0],accessor->rawDataConst(),pixelSize);
                        }
                        if (x == 0 && y == 0) {
                            // Because the sum of the weights must be 255,
                            // we cheat a bit, and weigh the center pixel differently in order
                            // to sum to 255 in total
                            // It's -(counts -1), because we'll add the center one implicitly
                            // through that calculation
                            weights[1] = (255 - ((i + 1) * (255 /(i+2) )) );
                        } else {
                            weights[1] = 255 /(i+2);
                        }


                        i++;
                        if (i>smudgeRadius){i=0;}
                        weights[0] = 255 - weights[1];
                        const quint8** cpixels = const_cast<const quint8**>(pixels);
                        cs->mixColorsOp()->mixColors(cpixels, weights,2, data);
                        memcpy(pixels[0],data,pixelSize);


                    }
                    x = x*(-1);
                }
                y = y*(-1);
            }

        }

        KoColor color = KoColor(pixels[0],cs);
        painter.setPaintColor(color);

        for (int l = 0; l < 2; l++){
            delete[] pixels[l];
        }
        // delete[] pixels;
        delete[] data;
    }


}
예제 #16
0
void KisBrush::mask(KisFixedPaintDeviceSP dst, const KoColor& color, double scaleX, double scaleY, double angle, const KisPaintInformation& info, double subPixelX, double subPixelY, qreal softnessFactor) const
{
    PlainColoringInformation pci(color.data());
    generateMaskAndApplyMaskOrCreateDab(dst, &pci, scaleX, scaleY, angle, info, subPixelX, subPixelY, softnessFactor);
}
예제 #17
0
inline void HairyBrush::plotPixel(int wx, int wy, const KoColor &color)
{
    m_dabAccessor->moveTo(wx, wy);
    m_compositeOp->composite(m_dabAccessor->rawData(), m_pixelSize, color.data() , m_pixelSize, 0, 0, 1, 1, OPACITY_OPAQUE_U8);
}
예제 #18
0
void SprayBrush::paint(KisPaintDeviceSP dab, KisPaintDeviceSP source,
                       const KisPaintInformation& info, qreal rotation, qreal scale,
                       const KoColor &color, const KoColor &bgColor)
{
    // initializing painter
    if (!m_painter) {
        m_painter = new KisPainter(dab);
        m_painter->setFillStyle(KisPainter::FillStyleForegroundColor);
        m_painter->setMaskImageSize(m_shapeProperties->width, m_shapeProperties->height);
        m_dabPixelSize = dab->colorSpace()->pixelSize();
        if (m_colorProperties->useRandomHSV) {
            m_transfo = dab->colorSpace()->createColorTransformation("hsv_adjustment", QHash<QString, QVariant>());
        }

        m_brushQImage = m_shapeProperties->image;
        if (!m_brushQImage.isNull()) {
            m_brushQImage = m_brushQImage.scaled(m_shapeProperties->width, m_shapeProperties->height);
        }
        m_imageDevice = new KisPaintDevice(dab->colorSpace());
    }


    qreal x = info.pos().x();
    qreal y = info.pos().y();
    KisRandomAccessorSP accessor = dab->createRandomAccessorNG(qRound(x), qRound(y));

    Q_ASSERT(color.colorSpace()->pixelSize() == dab->pixelSize());
    m_inkColor = color;
    KisCrossDeviceColorPicker colorPicker(source, m_inkColor);

    // apply size sensor
    m_radius = m_properties->radius * scale;

    // jitter movement
    if (m_properties->jitterMovement) {
        x = x + ((2 * m_radius * drand48()) - m_radius) * m_properties->amount;
        y = y + ((2 * m_radius * drand48()) - m_radius) * m_properties->amount;
    }

    // this is wrong for every shape except pixel and anti-aliased pixel


    if (m_properties->useDensity) {
        m_particlesCount = (m_properties->coverage * (M_PI * m_radius * m_radius));
    }
    else {
        m_particlesCount = m_properties->particleCount;
    }

    QHash<QString, QVariant> params;
    qreal nx, ny;
    int ix, iy;

    qreal angle;
    qreal length;
    qreal rotationZ = 0.0;
    qreal particleScale = 1.0;

    bool shouldColor = true;
    if (m_colorProperties->fillBackground) {
        m_painter->setPaintColor(bgColor);
        paintCircle(m_painter, x, y, m_radius);
    }

    QTransform m;
    m.reset();
    m.rotateRadians(-rotation + deg2rad(m_properties->brushRotation));
    m.scale(m_properties->scale, m_properties->scale);

    for (quint32 i = 0; i < m_particlesCount; i++) {
        // generate random angle
        angle = drand48() * M_PI * 2;

        // generate random length
        if (m_properties->gaussian) {
            length = qBound<qreal>(0.0, m_rand->nextGaussian(0.0, 0.50) , 1.0);
        }
        else {
            length = drand48();
        }

        if (m_shapeDynamicsProperties->enabled) {
            // rotation
            rotationZ = rotationAngle();

            if (m_shapeDynamicsProperties->followCursor) {

                rotationZ = linearInterpolation(rotationZ, angle, m_shapeDynamicsProperties->followCursorWeigth);
            }


            if (m_shapeDynamicsProperties->followDrawingAngle) {

                rotationZ = linearInterpolation(rotationZ, info.drawingAngle(), m_shapeDynamicsProperties->followDrawingAngleWeight);
            }

            // random size - scale
            if (m_shapeDynamicsProperties->randomSize) {
                particleScale = drand48();
            }
        }
        // generate polar coordinate
        nx = (m_radius * cos(angle)  * length);
        ny = (m_radius * sin(angle)  * length);

        // compute the height of the ellipse
        ny *= m_properties->aspect;

        // transform
        m.map(nx, ny, &nx, &ny);

        // color transformation

        if (shouldColor) {
            if (m_colorProperties->sampleInputColor) {
                colorPicker.pickOldColor(nx + x, ny + y, m_inkColor.data());
            }

            // mix the color with background color
            if (m_colorProperties->mixBgColor) {
                KoMixColorsOp * mixOp = dab->colorSpace()->mixColorsOp();

                const quint8 *colors[2];
                colors[0] = m_inkColor.data();
                colors[1] = bgColor.data();

                qint16 colorWeights[2];
                int MAX_16BIT = 255;
                qreal blend = info.pressure();

                colorWeights[0] = static_cast<quint16>(blend * MAX_16BIT);
                colorWeights[1] = static_cast<quint16>((1.0 - blend) * MAX_16BIT);
                mixOp->mixColors(colors, colorWeights, 2, m_inkColor.data());
            }

            if (m_colorProperties->useRandomHSV && m_transfo) {
                params["h"] = (m_colorProperties->hue / 180.0) * drand48();
                params["s"] = (m_colorProperties->saturation / 100.0) * drand48();
                params["v"] = (m_colorProperties->value / 100.0) * drand48();
                m_transfo->setParameters(params);
                m_transfo->transform(m_inkColor.data(), m_inkColor.data() , 1);
            }

            if (m_colorProperties->useRandomOpacity) {
                quint8 alpha = qRound(drand48() * OPACITY_OPAQUE_U8);
                m_inkColor.setOpacity(alpha);
                m_painter->setOpacity(alpha);
            }

            if (!m_colorProperties->colorPerParticle) {
                shouldColor = false;
            }
            m_painter->setPaintColor(m_inkColor);
        }

        qreal jitteredWidth = qMax(qreal(1.0), m_shapeProperties->width * particleScale);
        qreal jitteredHeight = qMax(qreal(1.0), m_shapeProperties->height * particleScale);

        if (m_shapeProperties->enabled){
        switch (m_shapeProperties->shape){
            // ellipse
            case 0:
            {
                if (m_shapeProperties->width == m_shapeProperties->height){
                    paintCircle(m_painter, nx + x, ny + y, qRound(jitteredWidth * 0.5));
                }
                else {
                    paintEllipse(m_painter, nx + x, ny + y, qRound(jitteredWidth * 0.5) , qRound(jitteredHeight * 0.5), rotationZ);
                }
                break;
            }
            // rectangle
            case 1:
            {
                paintRectangle(m_painter, nx + x, ny + y, qRound(jitteredWidth) , qRound(jitteredHeight), rotationZ);
                break;
            }
            // wu-particle
            case 2: {
                paintParticle(accessor, m_inkColor, nx + x, ny + y);
                break;
            }
            // pixel
            case 3: {
                ix = qRound(nx + x);
                iy = qRound(ny + y);
                accessor->moveTo(ix, iy);
                memcpy(accessor->rawData(), m_inkColor.data(), m_dabPixelSize);
                break;
            }
            case 4: {
                if (!m_brushQImage.isNull()) {

                    QTransform m;
                    m.rotate(rad2deg(rotationZ));

                    if (m_shapeDynamicsProperties->randomSize) {
                        m.scale(particleScale, particleScale);
                    }
                    m_transformed = m_brushQImage.transformed(m, Qt::SmoothTransformation);
                    m_imageDevice->convertFromQImage(m_transformed, 0);
                    KisRandomAccessorSP ac = m_imageDevice->createRandomAccessorNG(0, 0);
                    QRect rc = m_transformed.rect();

                    if (m_colorProperties->useRandomHSV && m_transfo) {

                        for (int y = rc.y(); y < rc.y() + rc.height(); y++) {
                            for (int x = rc.x(); x < rc.x() + rc.width(); x++) {
                                ac->moveTo(x, y);
                                m_transfo->transform(ac->rawData(), ac->rawData() , 1);
                            }
                        }
                    }

                    ix = qRound(nx + x - rc.width() * 0.5);
                    iy = qRound(ny + y - rc.height() * 0.5);
                    m_painter->bitBlt(QPoint(ix, iy), m_imageDevice, rc);
                    m_imageDevice->clear();
                    break;
                }
            }
            }
            // Auto-brush
        }
        else {
            QPointF hotSpot = m_brush->hotSpot(particleScale, particleScale, -rotationZ, info);
            QPointF pos(nx + x, ny + y);
            QPointF pt = pos - hotSpot;

            qint32 ix;
            qreal xFraction;
            qint32 iy;
            qreal yFraction;

            KisPaintOp::splitCoordinate(pt.x(), &ix, &xFraction);
            KisPaintOp::splitCoordinate(pt.y(), &iy, &yFraction);

            //KisFixedPaintDeviceSP dab;
            if (m_brush->brushType() == IMAGE ||
                    m_brush->brushType() == PIPE_IMAGE) {
                m_fixedDab = m_brush->paintDevice(m_fixedDab->colorSpace(), particleScale, -rotationZ, info, xFraction, yFraction);

                if (m_colorProperties->useRandomHSV && m_transfo) {
                    quint8 * dabPointer = m_fixedDab->data();
                    int pixelCount = m_fixedDab->bounds().width() * m_fixedDab->bounds().height();
                    m_transfo->transform(dabPointer, dabPointer, pixelCount);
                }

            }
            else {
                m_brush->mask(m_fixedDab, m_inkColor, particleScale, particleScale, -rotationZ, info, xFraction, yFraction);
            }
            m_painter->bltFixed(QPoint(ix, iy), m_fixedDab, m_fixedDab->bounds());
        }
    }
    // recover from jittering of color,
    // m_inkColor.opacity is recovered with every paint
}
예제 #19
0
void KoColorSlider::drawContents( QPainter *painter )
{
    QPixmap checker(8, 8);
    QPainter p(&checker);
    p.fillRect(0, 0, 4, 4, Qt::lightGray);
    p.fillRect(4, 0, 4, 4, Qt::darkGray);
    p.fillRect(0, 4, 4, 4, Qt::darkGray);
    p.fillRect(4, 4, 4, 4, Qt::lightGray);
    p.end();
    QRect contentsRect_(contentsRect());
    painter->fillRect(contentsRect_, QBrush(checker));

    if( !d->upToDate || d->pixmap.isNull() || d->pixmap.width() != contentsRect_.width()
        || d->pixmap.height() != contentsRect_.height() )
    {
        KoColor c = d->minColor; // smart way to fetch colorspace
        QColor color;

        const quint8 *colors[2];
        colors[0] = d->minColor.data();
        colors[1] = d->maxColor.data();

        KoMixColorsOp * mixOp = c.colorSpace()->mixColorsOp();

        QImage image(contentsRect_.width(), contentsRect_.height(), QImage::Format_ARGB32 );

        if( orientation() == Qt::Horizontal ) {
            for (int x = 0; x < contentsRect_.width(); x++) {

                qreal t = static_cast<qreal>(x) / (contentsRect_.width() - 1);

                qint16 colorWeights[2];
                colorWeights[0] = static_cast<quint8>((1.0 - t) * 255 + 0.5);
                colorWeights[1] = 255 - colorWeights[0];

                mixOp->mixColors(colors, colorWeights, 2, c.data());

                c.toQColor(&color);

                for (int y = 0; y < contentsRect_.height(); y++)
                image.setPixel(x, y, color.rgba());
            }
        }
        else {
            for (int y = 0; y < contentsRect_.height(); y++) {

                qreal t = static_cast<qreal>(y) / (contentsRect_.height() - 1);

                qint16 colorWeights[2];
                colorWeights[0] = static_cast<quint8>((t) * 255 + 0.5);
                colorWeights[1] = 255 - colorWeights[0];

                mixOp->mixColors(colors, colorWeights, 2, c.data());

                c.toQColor(&color);

                for (int x = 0; x < contentsRect_.width(); x++)
                image.setPixel(x, y, color.rgba());
            }
        }
        d->pixmap = QPixmap::fromImage(image);
        d->upToDate = true;
    }
    painter->drawPixmap( contentsRect_, d->pixmap, QRect( 0, 0, d->pixmap.width(), d->pixmap.height()) );
}
예제 #20
0
void cutOneWay(const KoColor &color,
               KisPaintDeviceSP src,
               KisPaintDeviceSP colorScribble,
               KisPaintDeviceSP backgroundScribble,
               KisPaintDeviceSP resultDevice,
               KisPaintDeviceSP maskDevice,
               const QRect &boundingRect)
{
    using namespace boost;

    KIS_ASSERT_RECOVER_RETURN(src->pixelSize() == 1);
    KIS_ASSERT_RECOVER_RETURN(colorScribble->pixelSize() == 1);
    KIS_ASSERT_RECOVER_RETURN(backgroundScribble->pixelSize() == 1);
    KIS_ASSERT_RECOVER_RETURN(maskDevice->pixelSize() == 1);
    KIS_ASSERT_RECOVER_RETURN(*resultDevice->colorSpace() == *color.colorSpace());

    KisLazyFillCapacityMap capacityMap(src, colorScribble, backgroundScribble, maskDevice, boundingRect);
    KisLazyFillGraph &graph = capacityMap.graph();

    std::vector<default_color_type> groups(num_vertices(graph));
    std::vector<int> residual_capacity(num_edges(graph), 0);

    std::vector<typename graph_traits<KisLazyFillGraph>::vertices_size_type> distance_vec(num_vertices(graph), 0);
    std::vector<typename graph_traits<KisLazyFillGraph>::edge_descriptor> predecessor_vec(num_vertices(graph));

    auto vertexIndexMap = get(boost::vertex_index, graph);

    typedef KisLazyFillGraph::vertex_descriptor Vertex;

    Vertex s(Vertex::LABEL_A);
    Vertex t(Vertex::LABEL_B);

    float maxFlow =
        boykov_kolmogorov_max_flow(graph,
                                   capacityMap,
                                   make_iterator_property_map(&residual_capacity[0], get(boost::edge_index, graph)),
                                   get(boost::edge_reverse, graph),
                                   make_iterator_property_map(&predecessor_vec[0], vertexIndexMap),
                                   make_iterator_property_map(&groups[0], vertexIndexMap),
                                   make_iterator_property_map(&distance_vec[0], vertexIndexMap),
                                   vertexIndexMap,
                                   s,
                                   t);
    Q_UNUSED(maxFlow);

    KisSequentialIterator dstIt(resultDevice, graph.rect());
    KisSequentialIterator mskIt(maskDevice, graph.rect());

    const int pixelSize = resultDevice->pixelSize();

    do {
        KisLazyFillGraph::vertex_descriptor v(dstIt.x(), dstIt.y());
        long vertex_idx = get(boost::vertex_index, graph, v);
        default_color_type label = groups[vertex_idx];

        if (label == black_color) {
            memcpy(dstIt.rawData(), color.data(), pixelSize);
            *mskIt.rawData() = 10 + (int(label) << 4);
        }
    } while (dstIt.nextPixel() && mskIt.nextPixel());
}
예제 #21
0
void SprayBrush::paintOutline(KisPaintDeviceSP dev , const KoColor &outlineColor, qreal posX, qreal posY, qreal radius)
{
    QList<QPointF> antiPixels;
    KisRandomAccessorSP accessor = dev->createRandomAccessorNG(qRound(posX), qRound(posY));

    for (int y = -radius + posY; y <= radius + posY; y++) {
        for (int x = -radius + posX; x <= radius + posX; x++) {
            accessor->moveTo(x, y);
            qreal alpha = dev->colorSpace()->opacityU8(accessor->rawData());

            if (alpha != 0) {
                // top left
                accessor->moveTo(x - 1, y - 1);
                if (dev->colorSpace()->opacityU8(accessor->rawData()) == 0) {
                    antiPixels.append(QPointF(x - 1, y - 1));
                    //continue;
                }

                // top
                accessor->moveTo(x, y - 1);
                if (dev->colorSpace()->opacityU8(accessor->rawData()) == 0) {
                    antiPixels.append(QPointF(x, y - 1));
                    //continue;
                }

                // top right
                accessor->moveTo(x + 1, y - 1);
                if (dev->colorSpace()->opacityU8(accessor->rawData()) == 0) {
                    antiPixels.append(QPointF(x + 1, y - 1));
                    //continue;
                }

                //left
                accessor->moveTo(x - 1, y);
                if (dev->colorSpace()->opacityU8(accessor->rawData()) == 0) {
                    antiPixels.append(QPointF(x - 1, y));
                    //continue;
                }

                //right
                accessor->moveTo(x + 1, y);
                if (dev->colorSpace()->opacityU8(accessor->rawData()) == 0) {
                    antiPixels.append(QPointF(x + 1, y));
                    //continue;
                }

                // bottom left
                accessor->moveTo(x - 1, y + 1);
                if (dev->colorSpace()->opacityU8(accessor->rawData()) == 0) {
                    antiPixels.append(QPointF(x - 1, y + 1));
                    //continue;
                }

                // bottom
                accessor->moveTo(x, y + 1);
                if (dev->colorSpace()->opacityU8(accessor->rawData()) == 0) {
                    antiPixels.append(QPointF(x, y + 1));
                    //continue;
                }

                // bottom right
                accessor->moveTo(x + 1, y + 1);
                if (dev->colorSpace()->opacityU8(accessor->rawData()) == 0) {
                    antiPixels.append(QPointF(x + 1, y + 1));
                    //continue;
                }
            }

        }
    }

    // anti-alias it
    int size = antiPixels.size();
    for (int i = 0; i < size; i++) {
        accessor->moveTo(antiPixels[i].x(), antiPixels[i].y());
        memcpy(accessor->rawData(), outlineColor.data(), dev->colorSpace()->pixelSize());
    }
}
예제 #22
0
void SprayBrush::paintMetaballs(KisPaintDeviceSP dev, const KisPaintInformation &info, const KoColor &painterColor) {
    // TODO: make adjustable?
    qreal MIN_TRESHOLD = m_mintresh;
    qreal MAX_TRESHOLD = m_maxtresh;

//    dbgPlugins << "MAX " << MAX_TRESHOLD;
//    dbgPlugins << "MIN " << MIN_TRESHOLD;

    KoColor color = painterColor;
    qreal posX = info.pos().x();
    qreal posY = info.pos().y();

    //int points = m_coverage * (m_radius * m_radius * M_PI);
    qreal ballRadius = m_width * 0.5;

    // generate metaballs
    QList<Metaball> list;
    for (int i = 0; i < m_particlesCount ; i++){
        qreal x = (2 * drand48() * m_radius) - m_radius;
        qreal y = (2 * drand48() * m_radius) - m_radius;
        list.append(
                    Metaball( x, 
                              y ,
                              drand48() *  ballRadius)
                    );
    }

 
    // paint it
    KisRandomAccessor accessor = dev->createRandomAccessor(0, 0);

    qreal sum = 0.0;
    m_computeArea.translate( -qRound(posX), -qRound(posY) );
    for (int y = m_computeArea.y(); y <= m_computeArea.height(); y++){
        for (int x = m_computeArea.x() ; x <= m_computeArea.width(); x++){

            sum = 0.0;        

            for (int i = 0; i < m_particlesCount; i++){
                sum += list[i].equation(x, y );
            }
           
            if (sum >= MIN_TRESHOLD && sum <= MAX_TRESHOLD){
                    if (sum < 0.0) sum = 0.0;
                    if (sum > 1.0) sum = 1.0;

                    color.setOpacity(OPACITY_OPAQUE * sum);
                    accessor.moveTo( x + posX ,y + posY );
                    memcpy(accessor.rawData(), color.data(), dev->colorSpace()->pixelSize() );
            }
        }
    }
    m_computeArea.translate( qRound(posX), qRound(posY) );

#if 0        
        KisPainter dabPainter(dev);
        dabPainter.setFillColor(color);
        dabPainter.setPaintColor(color);
        dabPainter.setFillStyle(KisPainter::FillStyleForegroundColor);

        for (int i = 0; i < m_particlesCount; i++){
                qreal x = list[i].x() + posX;
                qreal y = list[i].y() + posY;
                dabPainter.paintEllipse(x, y, list[i].radius() * 2,list[i].radius() * 2);
        }
#endif

}
예제 #23
0
KisSpacingInformation KisColorSmudgeOp::paintAt(const KisPaintInformation& info)
{
    KisBrushSP brush = m_brush;

    // Simple error catching
    if (!painter()->device() || !brush || !brush->canPaintFor(info))
        return 1.0;

    // get the scaling factor calculated by the size option
    qreal scale    = m_sizeOption.apply(info);
    qreal rotation = m_rotationOption.apply(info);

    if (checkSizeTooSmall(scale)) return KisSpacingInformation();

    setCurrentScale(scale);
    setCurrentRotation(rotation);

    QPointF scatteredPos =
        m_scatterOption.apply(info,
                              brush->maskWidth(scale, rotation, 0, 0, info),
                              brush->maskHeight(scale, rotation, 0, 0, info));

    QPointF hotSpot = brush->hotSpot(scale, scale, rotation, info);

    /**
     * Update the brush mask.
     *
     * Upon leaving the function:
     *   o m_maskDab stores the new mask
     *   o m_maskBounds stroes the extents of the mask paint device
     *   o m_dstDabRect stores the destination rect where the mask is going
     *     to be written to
     */
    updateMask(info, scale, rotation, scatteredPos);

    QPointF newCenterPos = QRectF(m_dstDabRect).center();
    QRect srcDabRect = m_dstDabRect.translated((m_lastPaintPos - newCenterPos).toPoint());


    /**
     * Save the center of the current dab to know where to read the
     * data during the next pass. We do not save scatteredPos here,
     * because it may slightly differ from the real center of the
     * brush (due to some rounding effects), which will result in
     * really weird quality.
     */
    m_lastPaintPos = QRectF(m_dstDabRect).center();

    KisSpacingInformation spacingInfo =
        effectiveSpacing(m_dstDabRect.width(), m_dstDabRect.height(),
                         m_spacingOption, info);

    if (m_firstRun) {
        m_firstRun = false;
        return spacingInfo;
    }


    // save the old opacity value and composite mode
    quint8               oldOpacity = painter()->opacity();
    QString              oldModeId = painter()->compositeOp()->id();
    qreal                fpOpacity  = (qreal(oldOpacity) / 255.0) * m_opacityOption.getOpacityf(info);

    KoColor color = painter()->paintColor();

    if (m_image && m_overlayModeOption.isChecked()) {
        m_image->blockUpdates();
        m_backgroundPainter->bitBlt(QPoint(), m_image->projection(), srcDabRect);
        m_image->unblockUpdates();
    }
    else {
        // IMPORTANT: clear the temporary painting device to color black with zero opacity
        //            it will only clear the extents of the brush
        m_tempDev->clear(QRect(QPoint(), m_dstDabRect.size()));
    }

    if (m_smudgeRateOption.getMode() == KisSmudgeOption::SMEARING_MODE) {
        // cut out the area from the canvas under the brush
        // and blit it to the temporary painting device
        if(m_smudgeRadiusOption.isChecked())
        {
            m_smudgeRadiusOption.apply(*m_smudgePainter,info,m_brush->width(),m_dstDabRect.center().x(),m_dstDabRect.center().y(),painter()->device());
            color = m_smudgePainter->paintColor();

        }
        m_smudgePainter->bitBlt(QPoint(), painter()->device(), srcDabRect);
    }
    else {
        QPoint pt = (srcDabRect.topLeft() + hotSpot).toPoint();
        // get the pixel on the canvas that lies beneath the hot spot
        // of the dab and fill  the temporary paint device with that color

        KoColor color = painter()->paintColor();



        if(m_smudgeRadiusOption.isChecked())
        {
            m_smudgeRadiusOption.apply(*m_smudgePainter,info,m_brush->width(),pt.x(),pt.y(),painter()->device());
            KoColor color2 =  m_smudgePainter->paintColor();
            m_smudgePainter->fill(0, 0, m_dstDabRect.width(), m_dstDabRect.height(),color2);

        }

        else
        {
            KisCrossDeviceColorPickerInt colorPicker(painter()->device(), color);
             colorPicker.pickColor(pt.x(), pt.y(), color.data());

             m_smudgePainter->fill(0, 0, m_dstDabRect.width(), m_dstDabRect.height(), color);

        }


    }

    // if the user selected the color smudge option
    // we will mix some color into the temporary painting device (m_tempDev)
    if (m_colorRateOption.isChecked()) {
        // this will apply the opacy (selected by the user) to copyPainter
        // (but fit the rate inbetween the range 0.0 to (1.0-SmudgeRate))
        qreal maxColorRate = qMax<qreal>(1.0 - m_smudgeRateOption.getRate(), 0.2);
        m_colorRateOption.apply(*m_colorRatePainter, info, 0.0, maxColorRate, fpOpacity);

        // paint a rectangle with the current color (foreground color)
        // or a gradient color (if enabled)
        // into the temporary painting device and use the user selected
        // composite mode
        KoColor color = painter()->paintColor();
        m_gradientOption.apply(color, m_gradient, info);
        m_colorRatePainter->fill(0, 0, m_dstDabRect.width(), m_dstDabRect.height(), color);
        
    }


    // if color is disabled (only smudge) and "overlay mode is enabled
    // then first blit the region under the brush from the image projection
    // to the painting device to prevent a rapid build up of alpha value
    // if the color to be smudged is semi transparent
    if (m_image && m_overlayModeOption.isChecked() && !m_colorRateOption.isChecked()) {
        painter()->setCompositeOp(COMPOSITE_COPY);
        painter()->setOpacity(OPACITY_OPAQUE_U8);
        m_image->blockUpdates();
        painter()->bitBlt(m_dstDabRect.topLeft(), m_image->projection(), m_dstDabRect);
        m_image->unblockUpdates();
    }


    // set opacity calculated by the rate option
    m_smudgeRateOption.apply(*painter(), info, 0.0, 1.0, fpOpacity);

    // then blit the temporary painting device on the canvas at the current brush position
    // the alpha mask (maskDab) will be used here to only blit the pixels that are in the area (shape) of the brush
    painter()->setCompositeOp(COMPOSITE_COPY);
    painter()->bitBltWithFixedSelection(m_dstDabRect.x(), m_dstDabRect.y(), m_tempDev, m_maskDab, m_dstDabRect.width(), m_dstDabRect.height());
    painter()->renderMirrorMaskSafe(m_dstDabRect, m_tempDev, 0, 0, m_maskDab,
                                    !m_dabCache->needSeparateOriginal());

    // restore orginal opacy and composite mode values
    painter()->setOpacity(oldOpacity);
    painter()->setCompositeOp(oldModeId);



    return spacingInfo;
}
예제 #24
0
void KoUniColorChooser::updateValues()
{
    KoColor tmpColor;
    m_HIn->blockSignals(true);
    m_SIn->blockSignals(true);
    m_VIn->blockSignals(true);
    m_RIn->blockSignals(true);
    m_GIn->blockSignals(true);
    m_BIn->blockSignals(true);

    if (cmykColorSpace()) {
        m_CIn->blockSignals(true);
        m_MIn->blockSignals(true);
        m_YIn->blockSignals(true);
        m_KIn->blockSignals(true);
    }

    m_LIn->blockSignals(true);
    m_aIn->blockSignals(true);
    m_bIn->blockSignals(true);

/*
    KoOldColor color = m_fgColor;

    int h = color.H();
    int s = color.S();
    int v = color.V();

    m_HIn->setValue(h);
    m_SIn->setValue(s);
    m_VIn->setValue(v);
*/
    tmpColor = m_currentColor;
    tmpColor.convertTo(rgbColorSpace());
    m_RIn->setValue(tmpColor.data()[2]);
    m_GIn->setValue(tmpColor.data()[1]);
    m_BIn->setValue(tmpColor.data()[0]);

    if(m_showOpacitySlider)
    {
        m_opacitySlider->blockSignals(true);
        m_opacityIn->blockSignals(true);

        KoColor minColor = tmpColor;
        tmpColor.colorSpace()->setOpacity(minColor.data(), OPACITY_TRANSPARENT_U8, 1);
        KoColor maxColor = tmpColor;
        tmpColor.colorSpace()->setOpacity(maxColor.data(), OPACITY_OPAQUE_U8, 1);

        m_opacitySlider->setColors(minColor, maxColor);
        m_opacitySlider->setValue(tmpColor.opacityF() * 100 );
        m_opacityIn->setValue(tmpColor.opacityF() * 100 );

        m_opacityIn->blockSignals(false);
        m_opacitySlider->blockSignals(false);
    }

    tmpColor = m_currentColor;
    tmpColor.convertTo(labColorSpace());
    m_LIn->setValue(((quint16 *)tmpColor.data())[0]/(256*256/100));
    m_aIn->setValue(((quint16 *)tmpColor.data())[1]/256);
    m_bIn->setValue(((quint16 *)tmpColor.data())[2]/256);

    if ( cmykColorSpace() ) {
        tmpColor = m_currentColor;
        tmpColor.convertTo(cmykColorSpace());
        m_CIn->setValue((tmpColor.data()[0]*100)/255);
        m_MIn->setValue((tmpColor.data()[1]*100/255));
        m_YIn->setValue((tmpColor.data()[2]*100)/255);
        m_KIn->setValue((tmpColor.data()[3]*100)/255);
    }

    m_HIn->blockSignals(false);
    m_SIn->blockSignals(false);
    m_VIn->blockSignals(false);
    m_RIn->blockSignals(false);
    m_GIn->blockSignals(false);
    m_BIn->blockSignals(false);

    if (cmykColorSpace()) {
        m_CIn->blockSignals(false);
        m_MIn->blockSignals(false);
        m_YIn->blockSignals(false);
        m_KIn->blockSignals(false);
    }

    m_LIn->blockSignals(false);
    m_aIn->blockSignals(false);
    m_bIn->blockSignals(false);
}