예제 #1
0
void KisFilterRandomPick::processImpl(KisPaintDeviceSP device,
                                      const QRect& applyRect,
                                      const KisFilterConfigurationSP config,
                                      KoUpdater* progressUpdater
                                      ) const
{
    Q_UNUSED(config);
    Q_ASSERT(!device.isNull());

    if (progressUpdater) {
        progressUpdater->setRange(0, applyRect.width() * applyRect.height());
    }
    int count = 0;

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

    QVariant value;
    int level = (config && config->getProperty("level", value)) ? value.toInt() : 50;
    int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100;
    double windowsize = (config && config->getProperty("windowsize", value)) ? value.toDouble() : 2.5;

    int seedThreshold = rand();
    int seedH = rand();
    int seedV = rand();

    if (config) {
        seedThreshold = config->getInt("seedThreshold", seedThreshold);
        seedH = config->getInt("seedH", seedH);
        seedV = config->getInt("seedV", seedV);
    }
    KisRandomGenerator randT(seedThreshold);
    KisRandomGenerator randH(seedH);
    KisRandomGenerator randV(seedV);

    KisSequentialIterator dstIt(device, applyRect);
    KisRandomConstAccessorSP srcRA = device->createRandomConstAccessorNG(0, 0);

    double threshold = (100 - level) / 100.0;

    qint16 weights[2];
    weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0];
    const quint8* pixels[2];
    KoMixColorsOp * mixOp = cs->mixColorsOp();
    do{
        if (randT.doubleRandomAt(dstIt.x(), dstIt.y()) > threshold) {
            int x = static_cast<int>(dstIt.x() + windowsize * (randH.doubleRandomAt(dstIt.x(), dstIt.y()) - 0.5));
            int y = static_cast<int>(dstIt.y() +  windowsize * (randV.doubleRandomAt(dstIt.x(), dstIt.y()) -0.5));
            srcRA->moveTo(x, y);
            pixels[0] = srcRA->oldRawData();
            pixels[1] = dstIt.oldRawData();
            mixOp->mixColors(pixels, weights, 2, dstIt.rawData());
        }
        if (progressUpdater) progressUpdater->setValue(++count);
    } while(dstIt.nextPixel());

}
예제 #2
0
void KoRgbU8ColorSpaceTester::testMixColorsAverage()
{
    const KoColorSpace* cs = KoColorSpaceRegistry::instance()->rgb8();
    KoMixColorsOp * mixOp = cs->mixColorsOp();

    // Test mixColors.
    quint8 pixel1[4];
    quint8 pixel2[4];
    quint8 outputPixel[4];

    pixel1[PIXEL_RED] = 255;
    pixel1[PIXEL_GREEN] = 255;
    pixel1[PIXEL_BLUE] = 255;
    pixel1[PIXEL_ALPHA] = 255;

    pixel2[PIXEL_RED] = 0;
    pixel2[PIXEL_GREEN] = 0;
    pixel2[PIXEL_BLUE] = 0;
    pixel2[PIXEL_ALPHA] = 0;

    const quint8 *pixelPtrs[2];

    pixelPtrs[0] = pixel1;
    pixelPtrs[1] = pixel2;

    mixOp->mixColors(pixelPtrs, 2, outputPixel);

    QCOMPARE((int)outputPixel[PIXEL_RED], 255);
    QCOMPARE((int)outputPixel[PIXEL_GREEN], 255);
    QCOMPARE((int)outputPixel[PIXEL_BLUE], 255);
    QCOMPARE((int)outputPixel[PIXEL_ALPHA], 127);

    pixel2[PIXEL_ALPHA] = 255;
    mixOp->mixColors(pixelPtrs, 2, outputPixel);

    QCOMPARE((int)outputPixel[PIXEL_RED], 127);
    QCOMPARE((int)outputPixel[PIXEL_GREEN], 127);
    QCOMPARE((int)outputPixel[PIXEL_BLUE], 127);
    QCOMPARE((int)outputPixel[PIXEL_ALPHA], 255);
}
예제 #3
0
KoColor KoColorSlider::currentColor() const
{
    const quint8 *colors[2];
    colors[0] = d->minColor.data();
    colors[1] = d->maxColor.data();
    KoMixColorsOp * mixOp = d->minColor.colorSpace()->mixColorsOp();
    KoColor c(d->minColor.colorSpace());
    qint16 weights[2];
    weights[1] = (value() - minimum()) / qreal(maximum() - minimum()) * 255;
    weights[0] = 255 - weights[1];
    mixOp->mixColors(colors, weights, 2, c.data());
    return c;
}
예제 #4
0
KisPaintDeviceSP KisShearVisitor::yShear(KisPaintDeviceSP src, qreal shearY, KoUpdater *progress)
{
    int start = progress->progress();

    KisPaintDeviceSP dst = KisPaintDeviceSP(new KisPaintDevice(src->colorSpace()));
    KoMixColorsOp * mixOp = src->colorSpace()->mixColorsOp();

    dst->setX(src->x());
    dst->setY(src->y());

    QRect r = src->exactBounds();

    qreal displacement;
    qint32 displacementInt;
    qreal weight;

    for (qint32 x = r.left(); x <= r.right(); x++) {

        //calculate displacement
        displacement = x * shearY;

        displacementInt = (qint32)(floor(displacement));
        weight = displacement - displacementInt;

        qint16 pixelWeights[2];

        pixelWeights[0] = static_cast<quint8>(weight * 255 + 0.5);
        pixelWeights[1] = 255 - pixelWeights[0];

        KisVLineConstIteratorPixel srcIt = src->createVLineIterator(x, r.y(), r.height() + 1);
        KisVLineIteratorPixel leftSrcIt = src->createVLineIterator(x, r.y() - 1, r.height() + 1);
        KisVLineIteratorPixel dstIt = dst->createVLineIterator(x, r.y() + displacementInt, r.height() + 1);

        while (!srcIt.isDone()) {

            const quint8 *pixelPtrs[2];

            pixelPtrs[0] = leftSrcIt.rawData();
            pixelPtrs[1] = srcIt.rawData();

            mixOp->mixColors(pixelPtrs, pixelWeights, 2, dstIt.rawData());

            ++srcIt;
            ++leftSrcIt;
            ++dstIt;
        }
        progress->setProgress(start + x);
    }
    return dst;
}
예제 #5
0
KisPaintDeviceSP KisShearVisitor::xShear(KisPaintDeviceSP src, qreal shearX, KoUpdater *progress)
{
    KisPaintDeviceSP dst = KisPaintDeviceSP(new KisPaintDevice(src->colorSpace()));
    dst->setX(src->x());
    dst->setY(src->y());

    QRect r = src->exactBounds();

    qreal displacement;
    qint32 displacementInt;
    qreal weight;

    KoMixColorsOp * mixOp = src->colorSpace()->mixColorsOp();

    for (qint32 y = r.top(); y <= r.bottom(); y++) {

        //calculate displacement
        displacement = -y * shearX;

        displacementInt = (qint32)(floor(displacement));
        weight = displacement - displacementInt;

        qint16 pixelWeights[2];

        pixelWeights[0] = static_cast<quint8>(weight * 255 + 0.5);
        pixelWeights[1] = 255 - pixelWeights[0];

        KisHLineConstIteratorPixel srcIt = src->createHLineIterator(r.x(), y, r.width() + 1);
        KisHLineConstIteratorPixel leftSrcIt = src->createHLineIterator(r.x() - 1, y, r.width() + 1);
        KisHLineIteratorPixel dstIt = dst->createHLineIterator(r.x() + displacementInt, y, r.width() + 1);

        while (!srcIt.isDone()) {

            const quint8 *pixelPtrs[2];

            pixelPtrs[0] = leftSrcIt.rawData();
            pixelPtrs[1] = srcIt.rawData();

            mixOp->mixColors(pixelPtrs, pixelWeights, 2, dstIt.rawData());

            ++srcIt;
            ++leftSrcIt;
            ++dstIt;
        }
        progress->setProgress(y);

    }
    return dst;
}
예제 #6
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()) );
}
예제 #7
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
}
예제 #8
0
void KisFilterNoise::processImpl(KisPaintDeviceSP device,
                                 const QRect& applyRect,
                                 const KisFilterConfiguration* config,
                                 KoUpdater* progressUpdater
                                ) const
{
    Q_ASSERT(!device.isNull());

    if (progressUpdater) {
        progressUpdater->setRange(0, applyRect.width() * applyRect.height());
    }
    int count = 0;

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

    QVariant value;
    int level = (config && config->getProperty("level", value)) ? value.toInt() : 50;
    int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100;

    KisSequentialIterator it(device, applyRect);

    quint8* interm = new quint8[cs->pixelSize()];
    double threshold = (100.0 - level) * 0.01;

    qint16 weights[2];
    weights[0] = (255 * opacity) / 100;
    weights[1] = 255 - weights[0];

    const quint8* pixels[2];
    pixels[0] = interm;

    KoMixColorsOp * mixOp = cs->mixColorsOp();

    int seedThreshold = rand();
    int seedRed = rand();
    int seedGreen = rand();
    int seedBlue = rand();

    if (config) {
        seedThreshold = config->getInt("seedThreshold", seedThreshold);
        seedRed = config->getInt("seedRed", seedRed);
        seedGreen = config->getInt("seedGreen", seedGreen);
        seedBlue = config->getInt("seedBlue", seedBlue);
    }

    KisRandomGenerator randt(seedThreshold);
    KisRandomGenerator randr(seedRed);
    KisRandomGenerator randg(seedGreen);
    KisRandomGenerator randb(seedBlue);

    do {
        if (randt.doubleRandomAt(it.x(), it.y()) > threshold) {
            // XXX: Added static_cast to get rid of warnings
            QColor c = qRgb(static_cast<int>((double)randr.doubleRandomAt(it.x(), it.y()) * 255),
                            static_cast<int>((double)randg.doubleRandomAt(it.x(), it.y()) * 255),
                            static_cast<int>((double)randb.doubleRandomAt(it.x(), it.y()) * 255));
            cs->fromQColor(c, interm, 0);
            pixels[1] = it.oldRawData();
            mixOp->mixColors(pixels, weights, 2, it.rawData());
        }
        if (progressUpdater) progressUpdater->setValue(++count);
    } while (it.nextPixel() && !(progressUpdater && progressUpdater->interrupted()));

    delete [] interm;
}
void KoRgbColorSpaceTester::testMixColors()
{
    const KoColorSpace* cs = KoColorSpaceRegistry::instance()->rgb8();
    KoMixColorsOp * mixOp = cs->mixColorsOp();

    // Test mixColors.
    quint8 pixel1[4];
    quint8 pixel2[4];
    quint8 outputPixel[4];

    pixel1[PIXEL_RED] = 255;
    pixel1[PIXEL_GREEN] = 255;
    pixel1[PIXEL_BLUE] = 255;
    pixel1[PIXEL_ALPHA] = 255;

    pixel2[PIXEL_RED] = 0;
    pixel2[PIXEL_GREEN] = 0;
    pixel2[PIXEL_BLUE] = 0;
    pixel2[PIXEL_ALPHA] = 0;

    const quint8 *pixelPtrs[2];
    qint16 weights[2];

    pixelPtrs[0] = pixel1;
    pixelPtrs[1] = pixel2;

    weights[0] = 255;
    weights[1] = 0;

    mixOp->mixColors(pixelPtrs, weights, 2, outputPixel);

    QVERIFY((int)outputPixel[PIXEL_RED] == 255);
    QVERIFY((int)outputPixel[PIXEL_GREEN] == 255);
    QVERIFY((int)outputPixel[PIXEL_BLUE] == 255);
    QVERIFY((int)outputPixel[PIXEL_ALPHA] == 255);

    weights[0] = 0;
    weights[1] = 255;

    mixOp->mixColors(pixelPtrs, weights, 2, outputPixel);

    QVERIFY((int)outputPixel[PIXEL_RED] == 0);
    QVERIFY((int)outputPixel[PIXEL_GREEN] == 0);
    QVERIFY((int)outputPixel[PIXEL_BLUE] == 0);
    QVERIFY((int)outputPixel[PIXEL_ALPHA] == 0);

    weights[0] = 128;
    weights[1] = 127;

    mixOp->mixColors(pixelPtrs, weights, 2, outputPixel);

    QVERIFY((int)outputPixel[PIXEL_RED] == 255);
    QVERIFY((int)outputPixel[PIXEL_GREEN] == 255);
    QVERIFY((int)outputPixel[PIXEL_BLUE] == 255);
    QVERIFY((int)outputPixel[PIXEL_ALPHA] == 128);

    pixel1[PIXEL_RED] = 200;
    pixel1[PIXEL_GREEN] = 100;
    pixel1[PIXEL_BLUE] = 50;
    pixel1[PIXEL_ALPHA] = 255;

    pixel2[PIXEL_RED] = 100;
    pixel2[PIXEL_GREEN] = 200;
    pixel2[PIXEL_BLUE] = 20;
    pixel2[PIXEL_ALPHA] = 255;

    mixOp->mixColors(pixelPtrs, weights, 2, outputPixel);

    QVERIFY((int)outputPixel[PIXEL_RED] == 150);
    QCOMPARE((int)outputPixel[PIXEL_GREEN], 149);
    QVERIFY((int)outputPixel[PIXEL_BLUE] == 35);
    QVERIFY((int)outputPixel[PIXEL_ALPHA] == 255);

    pixel1[PIXEL_RED] = 0;
    pixel1[PIXEL_GREEN] = 0;
    pixel1[PIXEL_BLUE] = 0;
    pixel1[PIXEL_ALPHA] = 0;

    pixel2[PIXEL_RED] = 255;
    pixel2[PIXEL_GREEN] = 255;
    pixel2[PIXEL_BLUE] = 255;
    pixel2[PIXEL_ALPHA] = 254;

    weights[0] = 89;
    weights[1] = 166;

    mixOp->mixColors(pixelPtrs, weights, 2, outputPixel);

    QVERIFY((int)outputPixel[PIXEL_RED] == 255);
    QVERIFY((int)outputPixel[PIXEL_GREEN] == 255);
    QVERIFY((int)outputPixel[PIXEL_BLUE] == 255);
    QVERIFY((int)outputPixel[PIXEL_ALPHA] == 165);
}
예제 #10
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()) );
}
예제 #11
0
void KisCubismFilter::fillPolyColor(KisPaintDeviceSP src,
                                    const QPoint& srcTopLeft,
                                    KisPaintDeviceSP dst,
                                    const QPoint & dstTopLeft,
                                    const QSize& size,
                                    KisPolygon* poly,
                                    const quint8* col,
                                    quint8* dest) const
// void KisCubismFilter::fillPolyColor (KisPaintDeviceSP src, KisPaintDeviceSP dst, KisPolygon* poly, const quint8* col, quint8* /*s*/, QRect rect) const
{
    Q_UNUSED(srcTopLeft);
    Q_UNUSED(dest);

    qint32         val;
    double         alpha;
    qint32         x, y;
    double          xx, yy;
    double          vec[2];
    QRect rect(dstTopLeft, size);
    qint32         x1 = rect.left(), y1 = rect.top(), x2 = rect.right(), y2 = rect.bottom();
//         qint32         selWidth, selHeight;
    qint32         *vals, *valsIter, *valsEnd;
    qint32         xs, ys, xe, ye;


    qint32 sx = (qint32)(*poly)[0].x();
    qint32 sy = (qint32)(*poly)[0].y();
    qint32 ex = (qint32)(*poly)[1].x();
    qint32 ey = (qint32)(*poly)[1].y();

    double dist = sqrt((double)(SQR(ex - sx) + SQR(ey - sy)));
    double oneOverDist = 0.0;
    if (dist > 0.0) {
        double oneOverDist = 1 / dist;
        vec[0] = (ex - sx) * oneOverDist;
        vec[1] = (ey - sy) * oneOverDist;
    }

    qint32 pixelSize = src->pixelSize();
    //get the extents of the polygon
    double dMinX, dMinY, dMaxX, dMaxY;
    poly->extents(dMinX, dMinY, dMaxX, dMaxY);
    qint32 minX = static_cast<qint32>(dMinX);
    qint32 minY = static_cast<qint32>(dMinY);
    qint32 maxX = static_cast<qint32>(dMaxX);
    qint32 maxY = static_cast<qint32>(dMaxY);
    qint32 sizeX = (maxX - minX) * SUPERSAMPLE;
    qint32 sizeY = (maxY - minY) * SUPERSAMPLE;

    qint32 *minScanlines = new qint32[sizeY];
    qint32 *minScanlinesIter = minScanlines;
    qint32 *maxScanlines = new qint32[sizeY];
    qint32 *maxScanlinesIter = maxScanlines;

    for (qint32 i = 0; i < sizeY; i++) {
        minScanlines[i] = maxX * SUPERSAMPLE;
        maxScanlines[i] = minX * SUPERSAMPLE;
    }

    if (poly->numberOfPoints()) {
        qint32 polyNpts = poly->numberOfPoints();

        xs = static_cast<qint32>((*poly)[polyNpts-1].x());
        ys = static_cast<qint32>((*poly)[polyNpts-1].y());
        xe = static_cast<qint32>((*poly)[0].x());
        ye = static_cast<qint32>((*poly)[0].y());

        xs *= SUPERSAMPLE;
        ys *= SUPERSAMPLE;
        xe *= SUPERSAMPLE;
        ye *= SUPERSAMPLE;

        convertSegment(xs, ys, xe, ye, minY * SUPERSAMPLE, minScanlines, maxScanlines, minX* SUPERSAMPLE, maxX* SUPERSAMPLE);

        KisPolygon::iterator it;

        for (it = poly->begin(); it != poly->end();) {
            xs = static_cast<qint32>((*it).x());
            ys = static_cast<qint32>((*it).y());
            ++it;

            if (it != poly->end()) {
                xe = static_cast<qint32>((*it).x());
                ye = static_cast<qint32>((*it).y());

                xs *= SUPERSAMPLE;
                ys *= SUPERSAMPLE;
                xe *= SUPERSAMPLE;
                ye *= SUPERSAMPLE;

                convertSegment(xs, ys, xe, ye, minY * SUPERSAMPLE, minScanlines, maxScanlines, minX* SUPERSAMPLE, maxX* SUPERSAMPLE);
            }
        }
    }

    KisRandomAccessor dstAccessor = dst->createRandomAccessor(0, 0);

    KoMixColorsOp * mixOp = src->colorSpace()->mixColorsOp();
    quint8* buf = new quint8[pixelSize];

    vals = new qint32[sizeX];
//         x1 = minX; x2 = maxX; y1 = minY; y2 = maxY;
    for (qint32 i = 0; i < sizeY; i++, minScanlinesIter++, maxScanlinesIter++) {
        if (!(i % SUPERSAMPLE)) {
            memset(vals, 0, sizeof(qint32) * sizeX);
        }

        yy = static_cast<double>(i) / static_cast<double>(SUPERSAMPLE) + minY;

        for (qint32 j = *minScanlinesIter; j < *maxScanlinesIter; j++) {
            x = j - minX * SUPERSAMPLE;
            vals[x] += 255;
        }

        if (!((i + 1) % SUPERSAMPLE)) {
            y = (i / SUPERSAMPLE) + minY;
            if (y >= y1 && y <= y2) {
                for (qint32 j = 0; j < sizeX; j += SUPERSAMPLE) {
                    x = (j / SUPERSAMPLE) + minX;

                    if (x >= x1 && x <= x2) {
                        for (val = 0, valsIter = &vals[j], valsEnd = &valsIter[SUPERSAMPLE]; valsIter < valsEnd; valsIter++) {
                            val += *valsIter;
                        }
                        val /= SQR(SUPERSAMPLE);

                        if (val > 0) {
                            xx = static_cast<double>(j) / static_cast<double>(SUPERSAMPLE) + minX;
                            alpha = calcAlphaBlend(vec, oneOverDist, xx - sx, yy - sy);

                            qint16 weights[2];
                            weights[0] = static_cast<quint8>(alpha * 255);
                            weights[1] = 255 - weights[0];

                            dstAccessor.moveTo(x, y);
                            memcpy(buf, dstAccessor.rawData(), sizeof(quint8) * pixelSize);

                            const quint8* colors[2];
                            colors[0] = col;
                            colors[1] = buf;

                            mixOp->mixColors(colors, weights, 2, dstAccessor.rawData());
                        }
                    }
                }
            }
        }
    }
    delete[] buf;
    delete[] vals;
    delete[] minScanlines;
    delete[] maxScanlines;
}