void KisPrescaledProjectionTest::testUpdates()
{
    PrescaledProjectionTester t;

    t.converter.setDocumentOffset(QPoint(10,10));

    t.converter.setCanvasWidgetSize(2*QSize(300,300));
    t.projection.notifyCanvasSizeChanged(2*QSize(300,300));


    t.converter.setZoom(0.50);
    t.projection.notifyZoomChanged();

    QVERIFY(TestUtil::checkQImage(t.projection.prescaledQImage(),
                                  "prescaled_projection_test",
                                  "testUpdates",
                                  "zoom50"));

    t.layer->setVisible(false);
    KisUpdateInfoSP info = t.projection.updateCache(t.image->bounds());
    t.projection.recalculateCache(info);

    QVERIFY(TestUtil::checkQImage(t.projection.prescaledQImage(),
                                  "prescaled_projection_test",
                                  "testUpdates",
                                  "cleared"));

    t.layer->setVisible(true);
    t.image->refreshGraph();

    // Update incrementally

    const int step = 73;
    const int patchOffset = -7;
    const int patchSize = 93;

    QList<KisUpdateInfoSP> infos;

    for(int y = 0; y < t.image->height(); y+=step) {
        for(int x = 0; x < t.image->width(); x+=step) {
            QRect patchRect(x - patchOffset, y - patchOffset,
                            patchSize, patchSize);

            infos.append(t.projection.updateCache(patchRect));
        }
    }

    foreach(KisUpdateInfoSP info, infos) {
        t.projection.recalculateCache(info);
    }
void KisShadeSelectorLine::paintEvent(QPaintEvent *)
{

    if (m_cachedColorSpace != m_parentProxy->colorSpace()) {
        m_realPixelCache = new KisPaintDevice(m_parentProxy->colorSpace());
        m_cachedColorSpace = m_parentProxy->colorSpace();
    }
    else {
        m_realPixelCache->clear();
    }

    int patchCount;
    int patchSpacing;

    if(m_gradient) {
        patchCount = width();
        patchSpacing = 0;
    }
    else {
        patchCount = m_patchCount;
        patchSpacing = 3;
    }
    qreal patchWidth = (width()-patchSpacing*patchCount)/qreal(patchCount);

    qreal hueStep=m_hueDelta/qreal(patchCount);
    qreal saturationStep=m_saturationDelta/qreal(patchCount);
    qreal valueStep=m_valueDelta/qreal(patchCount);

    qreal baseHue;
    qreal baseSaturation;
    qreal baseValue;
    m_parentProxy->converter()->
        getHsvF(m_realColor, &baseHue, &baseSaturation, &baseValue);

    int z=0;
    for(int i=-patchCount/2; i<=patchCount/2; i++) {
        if(i==0 && patchCount%2==0) continue;

        qreal hue = baseHue + (i * hueStep) + m_hueShift;
        while (hue < 0.0) hue += 1.0;
        while (hue > 1.0) hue -= 1.0;

        qreal saturation = qBound<qreal>(0., baseSaturation + (i * saturationStep) + m_saturationShift, 1.);
        qreal value = qBound<qreal>(0., baseValue + (i * valueStep) + m_valueShift, 1.);

        QRect patchRect(z * (patchWidth + patchSpacing), 0, patchWidth, m_lineHeight);
        KoColor patchColor = m_parentProxy->converter()->fromHsvF(hue, saturation, value);

        patchColor.convertTo(m_realPixelCache->colorSpace());
        m_realPixelCache->fill(patchRect, patchColor);

        z++;
    }

    QPainter wpainter(this);
    QImage renderedImage = m_parentProxy->converter()->toQImage(m_realPixelCache);
    wpainter.drawImage(0, 0, renderedImage);

    if(m_displayHelpText) {
        QString helpText(i18n("delta h=%1 s=%2 v=%3 shift h=%4 s=%5 v=%6",
                         m_hueDelta,
                         m_saturationDelta,
                         m_valueDelta,
                         m_hueShift,
                         m_saturationShift,
                         m_valueShift));
        wpainter.setPen(QColor(255,255,255));
        wpainter.drawText(rect(), helpText);
    }
}