Qt 4.8
Classes | Public Functions | Protected Functions | Protected Variables | Private Types | List of all members
QGradientCache Class Reference

Classes

struct  CacheInfo
 

Public Functions

const uintgetBuffer (const QGradient &gradient, int opacity)
 
int paletteSize () const
 

Protected Functions

uintaddCacheElement (quint64 hash_val, const QGradient &gradient, int opacity)
 
void generateGradientColorTable (const QGradient &g, uint *colorTable, int size, int opacity) const
 
int maxCacheSize () const
 

Protected Variables

QGradientColorTableHash cache
 
QMutex mutex
 

Private Types

typedef QMultiHash< quint64, CacheInfoQGradientColorTableHash
 

Detailed Description

Definition at line 4547 of file qpaintengine_raster.cpp.

Typedefs

◆ QGradientColorTableHash

Definition at line 4559 of file qpaintengine_raster.cpp.

Functions

◆ addCacheElement()

uint* QGradientCache::addCacheElement ( quint64  hash_val,
const QGradient gradient,
int  opacity 
)
inlineprotected

Definition at line 4592 of file qpaintengine_raster.cpp.

4592  {
4593  if (cache.size() == maxCacheSize()) {
4594  // may remove more than 1, but OK
4595  cache.erase(cache.begin() + (qrand() % maxCacheSize()));
4596  }
4597  CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());
4598  generateGradientColorTable(gradient, cache_entry.buffer, paletteSize(), opacity);
4599  return cache.insert(hash_val, cache_entry).value().buffer;
4600  }
QGradientColorTableHash cache
Q_CORE_EXPORT int qrand()
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
InterpolationMode interpolationMode() const
Returns the interpolation mode of this gradient.
Definition: qbrush.cpp:1607
QGradientStops stops() const
Returns the stop points for this gradient.
Definition: qbrush.cpp:1520
uint buffer[GRADIENT_STOPTABLE_SIZE]
QHash< Key, T >::iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:934
int size() const
Returns the number of items in the hash.
Definition: qhash.h:295
iterator begin()
Returns an STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:464
iterator erase(iterator it)
Removes the (key, value) pair associated with the iterator pos from the hash, and returns an iterator...
Definition: qhash.h:827
void generateGradientColorTable(const QGradient &g, uint *colorTable, int size, int opacity) const

◆ generateGradientColorTable()

void QGradientCache::generateGradientColorTable ( const QGradient g,
uint colorTable,
int  size,
int  opacity 
) const
inlineprotected

Definition at line 4606 of file qpaintengine_raster.cpp.

4607 {
4608  QGradientStops stops = gradient.stops();
4609  int stopCount = stops.count();
4610  Q_ASSERT(stopCount > 0);
4611 
4612  bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);
4613 
4614  if (stopCount == 2) {
4615  uint first_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
4616  uint second_color = ARGB_COMBINE_ALPHA(stops[1].second.rgba(), opacity);
4617 
4618  qreal first_stop = stops[0].first;
4619  qreal second_stop = stops[1].first;
4620 
4621  if (second_stop < first_stop) {
4622  qSwap(first_color, second_color);
4623  qSwap(first_stop, second_stop);
4624  }
4625 
4626  if (colorInterpolation) {
4627  first_color = PREMUL(first_color);
4628  second_color = PREMUL(second_color);
4629  }
4630 
4631  int first_index = qRound(first_stop * (GRADIENT_STOPTABLE_SIZE-1));
4632  int second_index = qRound(second_stop * (GRADIENT_STOPTABLE_SIZE-1));
4633 
4634  uint red_first = qRed(first_color) << 16;
4635  uint green_first = qGreen(first_color) << 16;
4636  uint blue_first = qBlue(first_color) << 16;
4637  uint alpha_first = qAlpha(first_color) << 16;
4638 
4639  uint red_second = qRed(second_color) << 16;
4640  uint green_second = qGreen(second_color) << 16;
4641  uint blue_second = qBlue(second_color) << 16;
4642  uint alpha_second = qAlpha(second_color) << 16;
4643 
4644  int i = 0;
4645  for (; i <= qMin(GRADIENT_STOPTABLE_SIZE, first_index); ++i) {
4646  if (colorInterpolation)
4647  colorTable[i] = first_color;
4648  else
4649  colorTable[i] = PREMUL(first_color);
4650  }
4651 
4652  if (i < second_index) {
4653  qreal reciprocal = qreal(1) / (second_index - first_index);
4654 
4655  int red_delta = qRound(int(red_second - red_first) * reciprocal);
4656  int green_delta = qRound(int(green_second - green_first) * reciprocal);
4657  int blue_delta = qRound(int(blue_second - blue_first) * reciprocal);
4658  int alpha_delta = qRound(int(alpha_second - alpha_first) * reciprocal);
4659 
4660  // rounding
4661  red_first += 1 << 15;
4662  green_first += 1 << 15;
4663  blue_first += 1 << 15;
4664  alpha_first += 1 << 15;
4665 
4666  for (; i < qMin(GRADIENT_STOPTABLE_SIZE, second_index); ++i) {
4667  red_first += red_delta;
4668  green_first += green_delta;
4669  blue_first += blue_delta;
4670  alpha_first += alpha_delta;
4671 
4672  const uint color = ((alpha_first << 8) & 0xff000000) | (red_first & 0xff0000)
4673  | ((green_first >> 8) & 0xff00) | (blue_first >> 16);
4674 
4675  if (colorInterpolation)
4676  colorTable[i] = color;
4677  else
4678  colorTable[i] = PREMUL(color);
4679  }
4680  }
4681 
4682  for (; i < GRADIENT_STOPTABLE_SIZE; ++i) {
4683  if (colorInterpolation)
4684  colorTable[i] = second_color;
4685  else
4686  colorTable[i] = PREMUL(second_color);
4687  }
4688 
4689  return;
4690  }
4691 
4692  uint current_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
4693  if (stopCount == 1) {
4694  current_color = PREMUL(current_color);
4695  for (int i = 0; i < size; ++i)
4696  colorTable[i] = current_color;
4697  return;
4698  }
4699 
4700  // The position where the gradient begins and ends
4701  qreal begin_pos = stops[0].first;
4702  qreal end_pos = stops[stopCount-1].first;
4703 
4704  int pos = 0; // The position in the color table.
4705  uint next_color;
4706 
4707  qreal incr = 1 / qreal(size); // the double increment.
4708  qreal dpos = 1.5 * incr; // current position in gradient stop list (0 to 1)
4709 
4710  // Up to first point
4711  colorTable[pos++] = PREMUL(current_color);
4712  while (dpos <= begin_pos) {
4713  colorTable[pos] = colorTable[pos - 1];
4714  ++pos;
4715  dpos += incr;
4716  }
4717 
4718  int current_stop = 0; // We always interpolate between current and current + 1.
4719 
4720  qreal t; // position between current left and right stops
4721  qreal t_delta; // the t increment per entry in the color table
4722 
4723  if (dpos < end_pos) {
4724  // Gradient area
4725  while (dpos > stops[current_stop+1].first)
4726  ++current_stop;
4727 
4728  if (current_stop != 0)
4729  current_color = ARGB_COMBINE_ALPHA(stops[current_stop].second.rgba(), opacity);
4730  next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
4731 
4732  if (colorInterpolation) {
4733  current_color = PREMUL(current_color);
4734  next_color = PREMUL(next_color);
4735  }
4736 
4737  qreal diff = stops[current_stop+1].first - stops[current_stop].first;
4738  qreal c = (diff == 0) ? qreal(0) : 256 / diff;
4739  t = (dpos - stops[current_stop].first) * c;
4740  t_delta = incr * c;
4741 
4742  while (true) {
4743  Q_ASSERT(current_stop < stopCount);
4744 
4745  int dist = qRound(t);
4746  int idist = 256 - dist;
4747 
4748  if (colorInterpolation)
4749  colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
4750  else
4751  colorTable[pos] = PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
4752 
4753  ++pos;
4754  dpos += incr;
4755 
4756  if (dpos >= end_pos)
4757  break;
4758 
4759  t += t_delta;
4760 
4761  int skip = 0;
4762  while (dpos > stops[current_stop+skip+1].first)
4763  ++skip;
4764 
4765  if (skip != 0) {
4766  current_stop += skip;
4767  if (skip == 1)
4768  current_color = next_color;
4769  else
4770  current_color = ARGB_COMBINE_ALPHA(stops[current_stop].second.rgba(), opacity);
4771  next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
4772 
4773  if (colorInterpolation) {
4774  if (skip != 1)
4775  current_color = PREMUL(current_color);
4776  next_color = PREMUL(next_color);
4777  }
4778 
4779  qreal diff = stops[current_stop+1].first - stops[current_stop].first;
4780  qreal c = (diff == 0) ? qreal(0) : 256 / diff;
4781  t = (dpos - stops[current_stop].first) * c;
4782  t_delta = incr * c;
4783  }
4784  }
4785  }
4786 
4787  // After last point
4788  current_color = PREMUL(ARGB_COMBINE_ALPHA(stops[stopCount - 1].second.rgba(), opacity));
4789  while (pos < size - 1) {
4790  colorTable[pos] = current_color;
4791  ++pos;
4792  }
4793 
4794  // Make sure the last color stop is represented at the end of the table
4795  colorTable[size - 1] = current_color;
4796 }
double qreal
Definition: qglobal.h:1193
unsigned char c[8]
Definition: qnumeric_p.h:62
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define GRADIENT_STOPTABLE_SIZE
Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb)
Definition: qrgb.h:66
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
T & first()
Returns a reference to the first item in the vector.
Definition: qvector.h:260
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
Definition: qrgb.h:57
#define ARGB_COMBINE_ALPHA(argb, alpha)
Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x)
Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b)
unsigned int uint
Definition: qglobal.h:996
static Bigint * diff(Bigint *a, Bigint *b)
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
Definition: qrgb.h:63
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203

◆ getBuffer()

const uint* QGradientCache::getBuffer ( const QGradient gradient,
int  opacity 
)
inline

Definition at line 4562 of file qpaintengine_raster.cpp.

4562  {
4563  quint64 hash_val = 0;
4564 
4565  QGradientStops stops = gradient.stops();
4566  for (int i = 0; i < stops.size() && i <= 2; i++)
4567  hash_val += stops[i].second.rgba();
4568 
4571 
4572  if (it == cache.constEnd())
4573  return addCacheElement(hash_val, gradient, opacity);
4574  else {
4575  do {
4576  const CacheInfo &cache_info = it.value();
4577  if (cache_info.stops == stops && cache_info.opacity == opacity && cache_info.interpolationMode == gradient.interpolationMode())
4578  return cache_info.buffer;
4579  ++it;
4580  } while (it != cache.constEnd() && it.key() == hash_val);
4581  // an exact match for these stops and opacity was not found, create new cache
4582  return addCacheElement(hash_val, gradient, opacity);
4583  }
4584  }
QHash< Key, T >::const_iterator constFind(const Key &key, const T &value) const
Returns an iterator pointing to the item with the key and the value in the hash.
Definition: qhash.h:992
#define it(className, varName)
QGradientColorTableHash cache
InterpolationMode interpolationMode() const
Returns the interpolation mode of this gradient.
Definition: qbrush.cpp:1607
QGradientStops stops() const
Returns the stop points for this gradient.
Definition: qbrush.cpp:1520
unsigned __int64 quint64
Definition: qglobal.h:943
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
static QReadWriteLock lock
Definition: proxyconf.cpp:399
uint * addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
friend class const_iterator
Definition: qhash.h:461

◆ maxCacheSize()

int QGradientCache::maxCacheSize ( ) const
inlineprotected

Definition at line 4588 of file qpaintengine_raster.cpp.

4588 { return 60; }

◆ paletteSize()

int QGradientCache::paletteSize ( ) const
inline

Definition at line 4586 of file qpaintengine_raster.cpp.

4586 { return GRADIENT_STOPTABLE_SIZE; }
#define GRADIENT_STOPTABLE_SIZE

Properties

◆ cache

QGradientColorTableHash QGradientCache::cache
protected

Definition at line 4602 of file qpaintengine_raster.cpp.

◆ mutex

QMutex QGradientCache::mutex
protected

Definition at line 4603 of file qpaintengine_raster.cpp.


The documentation for this class was generated from the following file: