! \internal Updates the internal map image buffer by going through the internal \ref QCPColorMapData and turning the data values into color pixels with \ref QCPColorGradient::colorize. This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image has been invalidated for a different reason (e.g. a change of the data range with \ref setDataRan
| 26752 | setInterpolate is true. |
| 26753 | */ |
| 26754 | void QCPColorMap::updateMapImage() |
| 26755 | { |
| 26756 | QCPAxis *keyAxis = mKeyAxis.data(); |
| 26757 | if (!keyAxis) return; |
| 26758 | if (mMapData->isEmpty()) return; |
| 26759 | |
| 26760 | const QImage::Format format = QImage::Format_ARGB32_Premultiplied; |
| 26761 | const int keySize = mMapData->keySize(); |
| 26762 | const int valueSize = mMapData->valueSize(); |
| 26763 | int keyOversamplingFactor = mInterpolate ? 1 : int(1.0+100.0/double(keySize)); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on |
| 26764 | int valueOversamplingFactor = mInterpolate ? 1 : int(1.0+100.0/double(valueSize)); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on |
| 26765 | |
| 26766 | // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: |
| 26767 | if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) |
| 26768 | mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); |
| 26769 | else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) |
| 26770 | mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); |
| 26771 | |
| 26772 | if (mMapImage.isNull()) |
| 26773 | { |
| 26774 | qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; |
| 26775 | mMapImage = QImage(QSize(10, 10), format); |
| 26776 | mMapImage.fill(Qt::black); |
| 26777 | } else |
| 26778 | { |
| 26779 | QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage |
| 26780 | if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) |
| 26781 | { |
| 26782 | // resize undersampled map image to actual key/value cell sizes: |
| 26783 | if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) |
| 26784 | mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); |
| 26785 | else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) |
| 26786 | mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); |
| 26787 | localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image |
| 26788 | } else if (!mUndersampledMapImage.isNull()) |
| 26789 | mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it |
| 26790 | |
| 26791 | const double *rawData = mMapData->mData; |
| 26792 | const unsigned char *rawAlpha = mMapData->mAlpha; |
| 26793 | if (keyAxis->orientation() == Qt::Horizontal) |
| 26794 | { |
| 26795 | const int lineCount = valueSize; |
| 26796 | const int rowCount = keySize; |
| 26797 | for (int line=0; line<lineCount; ++line) |
| 26798 | { |
| 26799 | QRgb* pixels = reinterpret_cast<QRgb*>(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) |
| 26800 | if (rawAlpha) |
| 26801 | mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); |
| 26802 | else |
| 26803 | mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); |
| 26804 | } |
| 26805 | } else // keyAxis->orientation() == Qt::Vertical |
| 26806 | { |
| 26807 | const int lineCount = keySize; |
| 26808 | const int rowCount = valueSize; |
| 26809 | for (int line=0; line<lineCount; ++line) |
| 26810 | { |
| 26811 | QRgb* pixels = reinterpret_cast<QRgb*>(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) |