//TODO: Let GL generate the texture using an FBO
void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const
{
    int pos = 0;
    QGradientStops s = gradient.stops();
    QVector<uint> colors(s.size());

    for (int i = 0; i < s.size(); ++i)
        colors[i] = s[i].second.rgba(); // Qt LIES! It returns ARGB (on little-endian AND on big-endian)

    bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);

    uint alpha = qRound(opacity * 256);
    uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);
    qreal incr = 1.0 / qreal(size);
    qreal fpos = 1.5 * incr;
    colorTable[pos++] = ARGB2RGBA(qPremultiply(current_color));

    while (fpos <= s.first().first) {
        colorTable[pos] = colorTable[pos - 1];
        pos++;
        fpos += incr;
    }

    if (colorInterpolation)
        current_color = qPremultiply(current_color);

    for (int i = 0; i < s.size() - 1; ++i) {
        qreal delta = 1/(s[i+1].first - s[i].first);
        uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);
        if (colorInterpolation)
            next_color = qPremultiply(next_color);

        while (fpos < s[i+1].first && pos < size) {
            int dist = int(256 * ((fpos - s[i].first) * delta));
            int idist = 256 - dist;
            if (colorInterpolation)
                colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
            else
                colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
            ++pos;
            fpos += incr;
        }
        current_color = next_color;
    }

    Q_ASSERT(s.size() > 0);

    uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
    for (;pos < size; ++pos)
        colorTable[pos] = last_color;

    // Make sure the last color stop is represented at the end of the table
    colorTable[size-1] = last_color;
}
예제 #2
0
void QRasterPlatformPixmap::fill(const QColor &color)
{
    uint pixel;

    if (image.depth() == 1) {
        int gray = qGray(color.rgba());
        // Pick the best approximate color in the image's colortable.
        if (qAbs(qGray(image.color(0)) - gray) < qAbs(qGray(image.color(1)) - gray))
            pixel = 0;
        else
            pixel = 1;
    } else if (image.depth() >= 15) {
        int alpha = color.alpha();
        if (alpha != 255) {
            if (!image.hasAlphaChannel()) {
                QImage::Format toFormat;
#if !(defined(__ARM_NEON__) || defined(__SSE2__))
                if (image.format() == QImage::Format_RGB16)
                    toFormat = QImage::Format_ARGB8565_Premultiplied;
                else if (image.format() == QImage::Format_RGB666)
                    toFormat = QImage::Format_ARGB6666_Premultiplied;
                else if (image.format() == QImage::Format_RGB555)
                    toFormat = QImage::Format_ARGB8555_Premultiplied;
                else if (image.format() == QImage::Format_RGB444)
                    toFormat = QImage::Format_ARGB4444_Premultiplied;
                else
#endif
                    toFormat = QImage::Format_ARGB32_Premultiplied;

                if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) {
                    image.detach();
                    image.d->format = toFormat;
                } else {
                    image = QImage(image.width(), image.height(), toFormat);
                }
            }
        }
        pixel = qPremultiply(color.rgba());
        const QPixelLayout *layout = &qPixelLayouts[image.format()];
        layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
    } else {
        pixel = 0;
        // ### what about 8 bits
    }

    image.fill(pixel);
}
예제 #3
0
void QRasterPlatformPixmap::fill(const QColor &color)
{
    uint pixel;

    if (image.depth() == 1) {
        int gray = qGray(color.rgba());
        // Pick the best approximate color in the image's colortable.
        if (qAbs(qGray(image.color(0)) - gray) < qAbs(qGray(image.color(1)) - gray))
            pixel = 0;
        else
            pixel = 1;
    } else if (image.depth() >= 15) {
        int alpha = color.alpha();
        if (alpha != 255) {
            if (!image.hasAlphaChannel()) {
                QImage::Format toFormat = qt_alphaVersionForPainting(image.format());
                if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) {
                    image.detach();
                    image.d->format = toFormat;
                } else {
                    image = QImage(image.width(), image.height(), toFormat);
                }
            }
        }
        pixel = qPremultiply(color.rgba());
        const QPixelLayout *layout = &qPixelLayouts[image.format()];
        layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
    } else if (image.format() == QImage::Format_Alpha8) {
        pixel = qAlpha(color.rgba());
    } else if (image.format() == QImage::Format_Grayscale8) {
        pixel = qGray(color.rgba());
    } else
    {
        pixel = 0;
        // ### what about 8 bit indexed?
    }

    image.fill(pixel);
}