mirror of
https://bitbucket.org/smil3y/katie.git
synced 2025-02-25 03:12:56 +00:00
fix gradient cache race-condition and heap-use-after-free
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
1b601ad247
commit
f4ceb2e759
3 changed files with 198 additions and 256 deletions
|
@ -57,6 +57,198 @@ static inline QRgb qConvertRgb16To32(uint c)
|
||||||
| ((((c) << 8) & 0xf80000) | (((c) << 3) & 0x70000));
|
| ((((c) << 8) & 0xf80000) | (((c) << 3) & 0x70000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QGradientData::generateGradientColorTable(const QGradient& gradient, int opacity)
|
||||||
|
{
|
||||||
|
QGradientStops stops = gradient.stops();
|
||||||
|
int stopCount = stops.count();
|
||||||
|
Q_ASSERT(stopCount > 0);
|
||||||
|
|
||||||
|
bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);
|
||||||
|
|
||||||
|
if (stopCount == 2) {
|
||||||
|
uint first_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
|
||||||
|
uint second_color = ARGB_COMBINE_ALPHA(stops[1].second.rgba(), opacity);
|
||||||
|
|
||||||
|
qreal first_stop = stops[0].first;
|
||||||
|
qreal second_stop = stops[1].first;
|
||||||
|
|
||||||
|
if (second_stop < first_stop) {
|
||||||
|
qSwap(first_color, second_color);
|
||||||
|
qSwap(first_stop, second_stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorInterpolation) {
|
||||||
|
first_color = PREMUL(first_color);
|
||||||
|
second_color = PREMUL(second_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
int first_index = qRound(first_stop * (GRADIENT_STOPTABLE_SIZE-1));
|
||||||
|
int second_index = qRound(second_stop * (GRADIENT_STOPTABLE_SIZE-1));
|
||||||
|
|
||||||
|
uint red_first = qRed(first_color) << 16;
|
||||||
|
uint green_first = qGreen(first_color) << 16;
|
||||||
|
uint blue_first = qBlue(first_color) << 16;
|
||||||
|
uint alpha_first = qAlpha(first_color) << 16;
|
||||||
|
|
||||||
|
uint red_second = qRed(second_color) << 16;
|
||||||
|
uint green_second = qGreen(second_color) << 16;
|
||||||
|
uint blue_second = qBlue(second_color) << 16;
|
||||||
|
uint alpha_second = qAlpha(second_color) << 16;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (; i <= qMin(GRADIENT_STOPTABLE_SIZE, first_index); ++i) {
|
||||||
|
if (colorInterpolation)
|
||||||
|
colorTable[i] = first_color;
|
||||||
|
else
|
||||||
|
colorTable[i] = PREMUL(first_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < second_index) {
|
||||||
|
qreal reciprocal = qreal(1) / (second_index - first_index);
|
||||||
|
|
||||||
|
int red_delta = qRound(int(red_second - red_first) * reciprocal);
|
||||||
|
int green_delta = qRound(int(green_second - green_first) * reciprocal);
|
||||||
|
int blue_delta = qRound(int(blue_second - blue_first) * reciprocal);
|
||||||
|
int alpha_delta = qRound(int(alpha_second - alpha_first) * reciprocal);
|
||||||
|
|
||||||
|
// rounding
|
||||||
|
red_first += 1 << 15;
|
||||||
|
green_first += 1 << 15;
|
||||||
|
blue_first += 1 << 15;
|
||||||
|
alpha_first += 1 << 15;
|
||||||
|
|
||||||
|
for (; i < qMin(GRADIENT_STOPTABLE_SIZE, second_index); ++i) {
|
||||||
|
red_first += red_delta;
|
||||||
|
green_first += green_delta;
|
||||||
|
blue_first += blue_delta;
|
||||||
|
alpha_first += alpha_delta;
|
||||||
|
|
||||||
|
const uint color = ((alpha_first << 8) & 0xff000000) | (red_first & 0xff0000)
|
||||||
|
| ((green_first >> 8) & 0xff00) | (blue_first >> 16);
|
||||||
|
|
||||||
|
if (colorInterpolation)
|
||||||
|
colorTable[i] = color;
|
||||||
|
else
|
||||||
|
colorTable[i] = PREMUL(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < GRADIENT_STOPTABLE_SIZE; ++i) {
|
||||||
|
if (colorInterpolation)
|
||||||
|
colorTable[i] = second_color;
|
||||||
|
else
|
||||||
|
colorTable[i] = PREMUL(second_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint current_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
|
||||||
|
if (stopCount == 1) {
|
||||||
|
current_color = PREMUL(current_color);
|
||||||
|
for (int i = 0; i < GRADIENT_STOPTABLE_SIZE; ++i)
|
||||||
|
colorTable[i] = current_color;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The position where the gradient begins and ends
|
||||||
|
qreal begin_pos = stops[0].first;
|
||||||
|
qreal end_pos = stops[stopCount-1].first;
|
||||||
|
|
||||||
|
int pos = 0; // The position in the color table.
|
||||||
|
uint next_color;
|
||||||
|
|
||||||
|
qreal incr = 1 / qreal(GRADIENT_STOPTABLE_SIZE); // the double increment.
|
||||||
|
qreal dpos = 1.5 * incr; // current position in gradient stop list (0 to 1)
|
||||||
|
|
||||||
|
// Up to first point
|
||||||
|
colorTable[pos++] = PREMUL(current_color);
|
||||||
|
while (dpos <= begin_pos) {
|
||||||
|
colorTable[pos] = colorTable[pos - 1];
|
||||||
|
++pos;
|
||||||
|
dpos += incr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int current_stop = 0; // We always interpolate between current and current + 1.
|
||||||
|
|
||||||
|
qreal t; // position between current left and right stops
|
||||||
|
qreal t_delta; // the t increment per entry in the color table
|
||||||
|
|
||||||
|
if (dpos < end_pos) {
|
||||||
|
// Gradient area
|
||||||
|
while (dpos > stops[current_stop+1].first)
|
||||||
|
++current_stop;
|
||||||
|
|
||||||
|
if (current_stop != 0)
|
||||||
|
current_color = ARGB_COMBINE_ALPHA(stops[current_stop].second.rgba(), opacity);
|
||||||
|
next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
|
||||||
|
|
||||||
|
if (colorInterpolation) {
|
||||||
|
current_color = PREMUL(current_color);
|
||||||
|
next_color = PREMUL(next_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal diff = stops[current_stop+1].first - stops[current_stop].first;
|
||||||
|
qreal c = (diff == 0) ? qreal(0) : 256 / diff;
|
||||||
|
t = (dpos - stops[current_stop].first) * c;
|
||||||
|
t_delta = incr * c;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Q_ASSERT(current_stop < stopCount);
|
||||||
|
|
||||||
|
int dist = qRound(t);
|
||||||
|
int idist = 256 - dist;
|
||||||
|
|
||||||
|
if (colorInterpolation)
|
||||||
|
colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
|
||||||
|
else
|
||||||
|
colorTable[pos] = PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
|
||||||
|
|
||||||
|
++pos;
|
||||||
|
dpos += incr;
|
||||||
|
|
||||||
|
if (dpos >= end_pos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
t += t_delta;
|
||||||
|
|
||||||
|
int skip = 0;
|
||||||
|
while (dpos > stops[current_stop+skip+1].first)
|
||||||
|
++skip;
|
||||||
|
|
||||||
|
if (skip != 0) {
|
||||||
|
current_stop += skip;
|
||||||
|
if (skip == 1)
|
||||||
|
current_color = next_color;
|
||||||
|
else
|
||||||
|
current_color = ARGB_COMBINE_ALPHA(stops[current_stop].second.rgba(), opacity);
|
||||||
|
next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
|
||||||
|
|
||||||
|
if (colorInterpolation) {
|
||||||
|
if (skip != 1)
|
||||||
|
current_color = PREMUL(current_color);
|
||||||
|
next_color = PREMUL(next_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal diff = stops[current_stop+1].first - stops[current_stop].first;
|
||||||
|
qreal c = (diff == 0) ? qreal(0) : 256 / diff;
|
||||||
|
t = (dpos - stops[current_stop].first) * c;
|
||||||
|
t_delta = incr * c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After last point
|
||||||
|
current_color = PREMUL(ARGB_COMBINE_ALPHA(stops[stopCount - 1].second.rgba(), opacity));
|
||||||
|
while (pos < GRADIENT_STOPTABLE_SIZE - 1) {
|
||||||
|
colorTable[pos] = current_color;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the last color stop is represented at the end of the table
|
||||||
|
colorTable[GRADIENT_STOPTABLE_SIZE - 1] = current_color;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Destination fetch. This is simple as we don't have to do bounds checks or
|
Destination fetch. This is simple as we don't have to do bounds checks or
|
||||||
transformations
|
transformations
|
||||||
|
|
|
@ -182,9 +182,10 @@ struct QGradientData
|
||||||
#define GRADIENT_STOPTABLE_SIZE 1024
|
#define GRADIENT_STOPTABLE_SIZE 1024
|
||||||
#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
|
#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
|
||||||
|
|
||||||
uint* colorTable; //[GRADIENT_STOPTABLE_SIZE];
|
uint colorTable[GRADIENT_STOPTABLE_SIZE];
|
||||||
|
|
||||||
bool alphaColor;
|
bool alphaColor;
|
||||||
|
|
||||||
|
void generateGradientColorTable(const QGradient& g, int opacity);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QTextureData
|
struct QTextureData
|
||||||
|
|
|
@ -3186,257 +3186,6 @@ QImage QRasterBuffer::bufferImage() const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class QGradientCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QGradientCache();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct CacheInfo
|
|
||||||
{
|
|
||||||
inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) :
|
|
||||||
stops(s), opacity(op), interpolationMode(mode) {}
|
|
||||||
uint buffer[GRADIENT_STOPTABLE_SIZE];
|
|
||||||
QGradientStops stops;
|
|
||||||
int opacity;
|
|
||||||
QGradient::InterpolationMode interpolationMode;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef QCache<quint64, CacheInfo> QGradientColorTableHash;
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline const uint *getBuffer(const QGradient &gradient, int opacity) {
|
|
||||||
quint64 hash_val = opacity + gradient.interpolationMode();
|
|
||||||
|
|
||||||
QGradientStops stops = gradient.stops();
|
|
||||||
for (int i = 0; i < stops.size() && i <= 2; i++)
|
|
||||||
hash_val += stops[i].second.rgba();
|
|
||||||
|
|
||||||
QMutexLocker lock(&mutex);
|
|
||||||
CacheInfo* match = cache.object(hash_val);
|
|
||||||
|
|
||||||
if (!match)
|
|
||||||
return addCacheElement(hash_val, gradient, opacity);
|
|
||||||
return match->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int paletteSize() const { return GRADIENT_STOPTABLE_SIZE; }
|
|
||||||
protected:
|
|
||||||
inline void generateGradientColorTable(const QGradient& g,
|
|
||||||
uint *colorTable,
|
|
||||||
int size, int opacity) const;
|
|
||||||
uint *addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) {
|
|
||||||
CacheInfo *cache_entry = new CacheInfo(gradient.stops(), opacity, gradient.interpolationMode());
|
|
||||||
generateGradientColorTable(gradient, cache_entry->buffer, paletteSize(), opacity);
|
|
||||||
cache.insert(hash_val, cache_entry);
|
|
||||||
return cache_entry->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
QGradientColorTableHash cache;
|
|
||||||
QMutex mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
QGradientCache::QGradientCache()
|
|
||||||
{
|
|
||||||
cache.setMaxCost(60);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, int opacity) const
|
|
||||||
{
|
|
||||||
QGradientStops stops = gradient.stops();
|
|
||||||
int stopCount = stops.count();
|
|
||||||
Q_ASSERT(stopCount > 0);
|
|
||||||
|
|
||||||
bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);
|
|
||||||
|
|
||||||
if (stopCount == 2) {
|
|
||||||
uint first_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
|
|
||||||
uint second_color = ARGB_COMBINE_ALPHA(stops[1].second.rgba(), opacity);
|
|
||||||
|
|
||||||
qreal first_stop = stops[0].first;
|
|
||||||
qreal second_stop = stops[1].first;
|
|
||||||
|
|
||||||
if (second_stop < first_stop) {
|
|
||||||
qSwap(first_color, second_color);
|
|
||||||
qSwap(first_stop, second_stop);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colorInterpolation) {
|
|
||||||
first_color = PREMUL(first_color);
|
|
||||||
second_color = PREMUL(second_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
int first_index = qRound(first_stop * (GRADIENT_STOPTABLE_SIZE-1));
|
|
||||||
int second_index = qRound(second_stop * (GRADIENT_STOPTABLE_SIZE-1));
|
|
||||||
|
|
||||||
uint red_first = qRed(first_color) << 16;
|
|
||||||
uint green_first = qGreen(first_color) << 16;
|
|
||||||
uint blue_first = qBlue(first_color) << 16;
|
|
||||||
uint alpha_first = qAlpha(first_color) << 16;
|
|
||||||
|
|
||||||
uint red_second = qRed(second_color) << 16;
|
|
||||||
uint green_second = qGreen(second_color) << 16;
|
|
||||||
uint blue_second = qBlue(second_color) << 16;
|
|
||||||
uint alpha_second = qAlpha(second_color) << 16;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (; i <= qMin(GRADIENT_STOPTABLE_SIZE, first_index); ++i) {
|
|
||||||
if (colorInterpolation)
|
|
||||||
colorTable[i] = first_color;
|
|
||||||
else
|
|
||||||
colorTable[i] = PREMUL(first_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < second_index) {
|
|
||||||
qreal reciprocal = qreal(1) / (second_index - first_index);
|
|
||||||
|
|
||||||
int red_delta = qRound(int(red_second - red_first) * reciprocal);
|
|
||||||
int green_delta = qRound(int(green_second - green_first) * reciprocal);
|
|
||||||
int blue_delta = qRound(int(blue_second - blue_first) * reciprocal);
|
|
||||||
int alpha_delta = qRound(int(alpha_second - alpha_first) * reciprocal);
|
|
||||||
|
|
||||||
// rounding
|
|
||||||
red_first += 1 << 15;
|
|
||||||
green_first += 1 << 15;
|
|
||||||
blue_first += 1 << 15;
|
|
||||||
alpha_first += 1 << 15;
|
|
||||||
|
|
||||||
for (; i < qMin(GRADIENT_STOPTABLE_SIZE, second_index); ++i) {
|
|
||||||
red_first += red_delta;
|
|
||||||
green_first += green_delta;
|
|
||||||
blue_first += blue_delta;
|
|
||||||
alpha_first += alpha_delta;
|
|
||||||
|
|
||||||
const uint color = ((alpha_first << 8) & 0xff000000) | (red_first & 0xff0000)
|
|
||||||
| ((green_first >> 8) & 0xff00) | (blue_first >> 16);
|
|
||||||
|
|
||||||
if (colorInterpolation)
|
|
||||||
colorTable[i] = color;
|
|
||||||
else
|
|
||||||
colorTable[i] = PREMUL(color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i < GRADIENT_STOPTABLE_SIZE; ++i) {
|
|
||||||
if (colorInterpolation)
|
|
||||||
colorTable[i] = second_color;
|
|
||||||
else
|
|
||||||
colorTable[i] = PREMUL(second_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint current_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
|
|
||||||
if (stopCount == 1) {
|
|
||||||
current_color = PREMUL(current_color);
|
|
||||||
for (int i = 0; i < size; ++i)
|
|
||||||
colorTable[i] = current_color;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The position where the gradient begins and ends
|
|
||||||
qreal begin_pos = stops[0].first;
|
|
||||||
qreal end_pos = stops[stopCount-1].first;
|
|
||||||
|
|
||||||
int pos = 0; // The position in the color table.
|
|
||||||
uint next_color;
|
|
||||||
|
|
||||||
qreal incr = 1 / qreal(size); // the double increment.
|
|
||||||
qreal dpos = 1.5 * incr; // current position in gradient stop list (0 to 1)
|
|
||||||
|
|
||||||
// Up to first point
|
|
||||||
colorTable[pos++] = PREMUL(current_color);
|
|
||||||
while (dpos <= begin_pos) {
|
|
||||||
colorTable[pos] = colorTable[pos - 1];
|
|
||||||
++pos;
|
|
||||||
dpos += incr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int current_stop = 0; // We always interpolate between current and current + 1.
|
|
||||||
|
|
||||||
qreal t; // position between current left and right stops
|
|
||||||
qreal t_delta; // the t increment per entry in the color table
|
|
||||||
|
|
||||||
if (dpos < end_pos) {
|
|
||||||
// Gradient area
|
|
||||||
while (dpos > stops[current_stop+1].first)
|
|
||||||
++current_stop;
|
|
||||||
|
|
||||||
if (current_stop != 0)
|
|
||||||
current_color = ARGB_COMBINE_ALPHA(stops[current_stop].second.rgba(), opacity);
|
|
||||||
next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
|
|
||||||
|
|
||||||
if (colorInterpolation) {
|
|
||||||
current_color = PREMUL(current_color);
|
|
||||||
next_color = PREMUL(next_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal diff = stops[current_stop+1].first - stops[current_stop].first;
|
|
||||||
qreal c = (diff == 0) ? qreal(0) : 256 / diff;
|
|
||||||
t = (dpos - stops[current_stop].first) * c;
|
|
||||||
t_delta = incr * c;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
Q_ASSERT(current_stop < stopCount);
|
|
||||||
|
|
||||||
int dist = qRound(t);
|
|
||||||
int idist = 256 - dist;
|
|
||||||
|
|
||||||
if (colorInterpolation)
|
|
||||||
colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
|
|
||||||
else
|
|
||||||
colorTable[pos] = PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
|
|
||||||
|
|
||||||
++pos;
|
|
||||||
dpos += incr;
|
|
||||||
|
|
||||||
if (dpos >= end_pos)
|
|
||||||
break;
|
|
||||||
|
|
||||||
t += t_delta;
|
|
||||||
|
|
||||||
int skip = 0;
|
|
||||||
while (dpos > stops[current_stop+skip+1].first)
|
|
||||||
++skip;
|
|
||||||
|
|
||||||
if (skip != 0) {
|
|
||||||
current_stop += skip;
|
|
||||||
if (skip == 1)
|
|
||||||
current_color = next_color;
|
|
||||||
else
|
|
||||||
current_color = ARGB_COMBINE_ALPHA(stops[current_stop].second.rgba(), opacity);
|
|
||||||
next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
|
|
||||||
|
|
||||||
if (colorInterpolation) {
|
|
||||||
if (skip != 1)
|
|
||||||
current_color = PREMUL(current_color);
|
|
||||||
next_color = PREMUL(next_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal diff = stops[current_stop+1].first - stops[current_stop].first;
|
|
||||||
qreal c = (diff == 0) ? qreal(0) : 256 / diff;
|
|
||||||
t = (dpos - stops[current_stop].first) * c;
|
|
||||||
t_delta = incr * c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// After last point
|
|
||||||
current_color = PREMUL(ARGB_COMBINE_ALPHA(stops[stopCount - 1].second.rgba(), opacity));
|
|
||||||
while (pos < size - 1) {
|
|
||||||
colorTable[pos] = current_color;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the last color stop is represented at the end of the table
|
|
||||||
colorTable[size - 1] = current_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(QGradientCache, qt_gradient_cache)
|
|
||||||
|
|
||||||
|
|
||||||
void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe)
|
void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe)
|
||||||
{
|
{
|
||||||
rasterBuffer = rb;
|
rasterBuffer = rb;
|
||||||
|
@ -3471,7 +3220,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
|
||||||
type = LinearGradient;
|
type = LinearGradient;
|
||||||
const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
|
const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
|
||||||
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
|
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
|
||||||
gradient.colorTable = const_cast<uint*>(qt_gradient_cache()->getBuffer(*g, alpha));
|
gradient.generateGradientColorTable(*g, alpha);
|
||||||
gradient.spread = g->spread();
|
gradient.spread = g->spread();
|
||||||
|
|
||||||
QLinearGradientData &linearData = gradient.linear;
|
QLinearGradientData &linearData = gradient.linear;
|
||||||
|
@ -3488,7 +3237,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
|
||||||
type = RadialGradient;
|
type = RadialGradient;
|
||||||
const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());
|
const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());
|
||||||
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
|
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
|
||||||
gradient.colorTable = const_cast<uint*>(qt_gradient_cache()->getBuffer(*g, alpha));
|
gradient.generateGradientColorTable(*g, alpha);
|
||||||
gradient.spread = g->spread();
|
gradient.spread = g->spread();
|
||||||
|
|
||||||
QRadialGradientData &radialData = gradient.radial;
|
QRadialGradientData &radialData = gradient.radial;
|
||||||
|
@ -3509,7 +3258,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
|
||||||
type = ConicalGradient;
|
type = ConicalGradient;
|
||||||
const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());
|
const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());
|
||||||
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
|
gradient.alphaColor = !brush.isOpaque() || alpha != 256;
|
||||||
gradient.colorTable = const_cast<uint*>(qt_gradient_cache()->getBuffer(*g, alpha));
|
gradient.generateGradientColorTable(*g, alpha);
|
||||||
gradient.spread = QGradient::RepeatSpread;
|
gradient.spread = QGradient::RepeatSpread;
|
||||||
|
|
||||||
QConicalGradientData &conicalData = gradient.conical;
|
QConicalGradientData &conicalData = gradient.conical;
|
||||||
|
|
Loading…
Add table
Reference in a new issue