//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; }
void saveGradientStops(QTextStream &str, const QGradient *g) { QGradientStops stops = g->stops(); if (g->interpolationMode() == QGradient::ColorInterpolation) { bool constantAlpha = true; int alpha = stops.at(0).second.alpha(); for (int i = 1; i < stops.size(); ++i) constantAlpha &= (stops.at(i).second.alpha() == alpha); if (!constantAlpha) { const qreal spacing = qreal(0.02); QGradientStops newStops; QRgb fromColor = PREMUL(stops.at(0).second.rgba()); QRgb toColor; for (int i = 0; i + 1 < stops.size(); ++i) { int parts = qCeil((stops.at(i + 1).first - stops.at(i).first) / spacing); newStops.append(stops.at(i)); toColor = PREMUL(stops.at(i + 1).second.rgba()); if (parts > 1) { qreal step = (stops.at(i + 1).first - stops.at(i).first) / parts; for (int j = 1; j < parts; ++j) { QRgb color = INV_PREMUL(INTERPOLATE_PIXEL_256(fromColor, 256 - 256 * j / parts, toColor, 256 * j / parts)); newStops.append(QGradientStop(stops.at(i).first + j * step, QColor::fromRgba(color))); } } fromColor = toColor; } newStops.append(stops.back()); stops = newStops; } } foreach(QGradientStop stop, stops) { QString color = QString::fromLatin1("#%1%2%3") .arg(stop.second.red(), 2, 16, QLatin1Char('0')) .arg(stop.second.green(), 2, 16, QLatin1Char('0')) .arg(stop.second.blue(), 2, 16, QLatin1Char('0')); str << QLatin1String(" <stop offset=\"")<< stop.first << QLatin1String("\" ") << QLatin1String("stop-color=\"") << color << QLatin1String("\" ") << QLatin1String("stop-opacity=\"") << stop.second.alphaF() <<QLatin1String("\" />\n"); }
void QCosmeticStroker::setup() { blend = state->penData.blend; if (state->clip && state->clip->enabled && state->clip->hasRectClip && !state->clip->clipRect.isEmpty()) { clip &= state->clip->clipRect; blend = state->penData.unclipped_blend; } int strokeSelection = 0; if (blend == state->penData.unclipped_blend && state->penData.type == QSpanData::Solid && (state->penData.rasterBuffer->format == QImage::Format_ARGB32_Premultiplied || state->penData.rasterBuffer->format == QImage::Format_RGB32) && state->compositionMode() == QPainter::CompositionMode_SourceOver) strokeSelection |= FastDraw; if (state->renderHints & QPainter::Antialiasing) strokeSelection |= AntiAliased; const QVector<qreal> &penPattern = state->lastPen.dashPattern(); if (penPattern.isEmpty()) { Q_ASSERT(!pattern && !reversePattern); pattern = 0; reversePattern = 0; patternLength = 0; patternSize = 0; } else { pattern = (int *)malloc(penPattern.size()*sizeof(int)); reversePattern = (int *)malloc(penPattern.size()*sizeof(int)); patternSize = penPattern.size(); patternLength = 0; for (int i = 0; i < patternSize; ++i) { patternLength += (int) qMax(1. , penPattern.at(i)*64.); pattern[i] = patternLength; } patternLength = 0; for (int i = 0; i < patternSize; ++i) { patternLength += (int) qMax(1., penPattern.at(patternSize - 1 - i)*64.); reversePattern[i] = patternLength; } strokeSelection |= Dashed; // qDebug() << "setup: size=" << patternSize << "length=" << patternLength/64.; } stroke = strokeLine(strokeSelection); qreal width = state->lastPen.widthF(); if (width == 0) opacity = 256; else if (state->lastPen.isCosmetic()) opacity = (int) 256*width; else opacity = (int) 256*width*state->txscale; opacity = qBound(0, opacity, 256); drawCaps = state->lastPen.capStyle() != Qt::FlatCap; if (strokeSelection & FastDraw) { color = INTERPOLATE_PIXEL_256(state->penData.solid.color, opacity, 0, 0); QRasterBuffer *buffer = state->penData.rasterBuffer; pixels = (uint *)buffer->buffer(); ppl = buffer->bytesPerLine()>>2; }