diff options
Diffstat (limited to 'src/gui/painting/qpaintengine_raster.cpp')
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 125 |
1 files changed, 56 insertions, 69 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index d276bcdccd..f62373d4ef 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -98,7 +98,6 @@ public: Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp -#define qreal_to_fixed_26_6(f) (int(f * 64)) #define qt_swap_int(x, y) { int tmp = (x); (x) = (y); (y) = tmp; } #define qt_swap_qreal(x, y) { qreal tmp = (x); (x) = (y); (y) = tmp; } @@ -144,9 +143,9 @@ bool QRasterPaintEngine::clearTypeFontsEnabled() /******************************************************************************** * Span functions */ -static void qt_span_fill_clipRect(int count, const QSpan *spans, void *userData); -static void qt_span_fill_clipped(int count, const QSpan *spans, void *userData); -static void qt_span_clip(int count, const QSpan *spans, void *userData); +static void qt_span_fill_clipRect(int count, const QT_FT_Span *spans, void *userData); +static void qt_span_fill_clipped(int count, const QT_FT_Span *spans, void *userData); +static void qt_span_clip(int count, const QT_FT_Span *spans, void *userData); struct ClipData { @@ -241,8 +240,7 @@ QRasterPaintEnginePrivate::QRasterPaintEnginePrivate() : /*! \class QRasterPaintEngine - \preliminary - \ingroup qws + \internal \inmodule QtGui \since 4.2 @@ -277,15 +275,6 @@ QRasterPaintEnginePrivate::QRasterPaintEnginePrivate() : */ /*! - \typedef QSpan - \relates QRasterPaintEngine - - A struct equivalent to QT_FT_Span, containing a position (x, - y), the span's length in pixels and its color/coverage (a value - ranging from 0 to 255). -*/ - -/*! \since 4.5 Creates a raster based paint engine for operating on the given @@ -416,13 +405,7 @@ bool QRasterPaintEngine::begin(QPaintDevice *device) QRasterPaintEngineState *s = state(); ensureOutlineMapper(); - d->outlineMapper->m_clip_rect = d->deviceRect; - - if (d->outlineMapper->m_clip_rect.width() > QT_RASTER_COORD_LIMIT) - d->outlineMapper->m_clip_rect.setWidth(QT_RASTER_COORD_LIMIT); - if (d->outlineMapper->m_clip_rect.height() > QT_RASTER_COORD_LIMIT) - d->outlineMapper->m_clip_rect.setHeight(QT_RASTER_COORD_LIMIT); - + d->outlineMapper->setClipRect(d->deviceRect); d->rasterizer->setClipRect(d->deviceRect); s->penData.init(d->rasterBuffer.data(), this); @@ -516,6 +499,7 @@ QRasterPaintEngineState::QRasterPaintEngineState() txscale = 1.; + flag_bits = 0; flags.fast_pen = true; flags.non_complex_pen = false; flags.antialiased = false; @@ -2277,7 +2261,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)) { RotationType rotationType = qRotationType(s->matrix); - Q_ASSUME(d->rasterBuffer->format < QImage::NImageFormats); + Q_ASSERT(d->rasterBuffer->format < QImage::NImageFormats); const QPixelLayout::BPP plBpp = qPixelLayouts[d->rasterBuffer->format].bpp; if (rotationType != NoRotation && qMemRotateFunctions[plBpp][rotationType] && img.rect().contains(sr.toAlignedRect())) { @@ -2358,9 +2342,16 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe } SrcOverScaleFunc func = qScaleFunctions[d->rasterBuffer->format][img.format()]; if (func && (!clip || clip->hasRectClip)) { + QRectF tr = qt_mapRect_non_normalizing(r, s->matrix); + if (!s->flags.antialiased) { + tr.setX(qRound(tr.x())); + tr.setY(qRound(tr.y())); + tr.setWidth(qRound(tr.width())); + tr.setHeight(qRound(tr.height())); + } func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(), img.bits(), img.bytesPerLine(), img.height(), - qt_mapRect_non_normalizing(r, s->matrix), sr, + tr, sr, !clip ? d->deviceRect : clip->clipRect, s->intOpacity); return; @@ -2670,7 +2661,7 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx return; const int NSPANS = 512; - QSpan spans[NSPANS]; + QT_FT_Span spans[NSPANS]; int current = 0; const int x1 = x0 + w; @@ -3406,16 +3397,18 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSp // Boundaries int w = image.width(); int h = image.height(); - int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height()); - int ymin = qMax(qRound(pos.y()), 0); - int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width()); - int xmin = qMax(qRound(pos.x()), 0); + int px = qRound(pos.x()); + int py = qRound(pos.y()); + int ymax = qMin(py + h, d->rasterBuffer->height()); + int ymin = qMax(py, 0); + int xmax = qMin(px + w, d->rasterBuffer->width()); + int xmin = qMax(px, 0); - int x_offset = xmin - qRound(pos.x()); + int x_offset = xmin - px; QImage::Format format = image.format(); for (int y = ymin; y < ymax; ++y) { - const uchar *src = image.scanLine(y - qRound(pos.y())); + const uchar *src = image.scanLine(y - py); if (format == QImage::Format_MonoLSB) { for (int x = 0; x < xmax - xmin; ++x) { int src_x = x + x_offset; @@ -3720,15 +3713,9 @@ bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mo QImage::Format dFormat = rasterBuffer->format; QImage::Format sFormat = image.format(); - // Formats must match or source format must be a subset of destination format - if (dFormat != sFormat && image.pixelFormat().alphaUsage() == QPixelFormat::IgnoresAlpha) { - if ((sFormat == QImage::Format_RGB32 && dFormat == QImage::Format_ARGB32) - || (sFormat == QImage::Format_RGBX8888 && dFormat == QImage::Format_RGBA8888) - || (sFormat == QImage::Format_RGBX64 && dFormat == QImage::Format_RGBA64)) - sFormat = dFormat; - else - sFormat = qt_maybeAlphaVersionWithSameDepth(sFormat); // this returns premul formats - } + // Formats must match or source format must be an opaque version of destination format + if (dFormat != sFormat && image.pixelFormat().alphaUsage() == QPixelFormat::IgnoresAlpha) + dFormat = qt_maybeDataCompatibleOpaqueVersion(dFormat); return (dFormat == sFormat); } @@ -3815,7 +3802,7 @@ void QClipData::initialize() return; if (!m_clipLines) - m_clipLines = (ClipLine *)calloc(sizeof(ClipLine), clipSpanHeight); + m_clipLines = (ClipLine *)calloc(clipSpanHeight, sizeof(ClipLine)); Q_CHECK_PTR(m_clipLines); QT_TRY { @@ -3827,7 +3814,7 @@ void QClipData::initialize() const int numRects = clipRegion.rectCount(); const int maxSpans = (ymax - ymin) * numRects; allocated = qMax(allocated, maxSpans); - m_spans = (QSpan *)malloc(allocated * sizeof(QSpan)); + m_spans = (QT_FT_Span *)malloc(allocated * sizeof(QT_FT_Span)); Q_CHECK_PTR(m_spans); int y = 0; @@ -3853,7 +3840,7 @@ void QClipData::initialize() for (int r = firstInBand; r <= lastInBand; ++r) { const QRect &currRect = rects[r]; - QSpan *span = m_spans + count; + QT_FT_Span *span = m_spans + count; span->x = currRect.x(); span->len = currRect.width(); span->y = y; @@ -3877,7 +3864,7 @@ void QClipData::initialize() return; } - m_spans = (QSpan *)malloc(allocated * sizeof(QSpan)); + m_spans = (QT_FT_Span *)malloc(allocated * sizeof(QT_FT_Span)); Q_CHECK_PTR(m_spans); if (hasRectClip) { @@ -3890,7 +3877,7 @@ void QClipData::initialize() const int len = clipRect.width(); while (y < ymax) { - QSpan *span = m_spans + count; + QT_FT_Span *span = m_spans + count; span->x = xmin; span->len = len; span->y = y; @@ -4029,16 +4016,16 @@ void QClipData::setClipRegion(const QRegion ®ion) \internal spans must be sorted on y */ -static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, - const QSpan *spans, const QSpan *end, - QSpan **outSpans, int available) +static const QT_FT_Span *qt_intersect_spans(const QClipData *clip, int *currentClip, + const QT_FT_Span *spans, const QT_FT_Span *end, + QT_FT_Span **outSpans, int available) { const_cast<QClipData *>(clip)->initialize(); - QSpan *out = *outSpans; + QT_FT_Span *out = *outSpans; - const QSpan *clipSpans = clip->m_spans + *currentClip; - const QSpan *clipEnd = clip->m_spans + clip->count; + const QT_FT_Span *clipSpans = clip->m_spans + *currentClip; + const QT_FT_Span *clipEnd = clip->m_spans + clip->count; while (available && spans < end ) { if (clipSpans >= clipEnd) { @@ -4092,7 +4079,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, return spans; } -static void qt_span_fill_clipped(int spanCount, const QSpan *spans, void *userData) +static void qt_span_fill_clipped(int spanCount, const QT_FT_Span *spans, void *userData) { // qDebug() << "qt_span_fill_clipped" << spanCount; QSpanData *fillData = reinterpret_cast<QSpanData *>(userData); @@ -4100,11 +4087,11 @@ static void qt_span_fill_clipped(int spanCount, const QSpan *spans, void *userDa Q_ASSERT(fillData->blend && fillData->unclipped_blend); const int NSPANS = 512; - QSpan cspans[NSPANS]; + QT_FT_Span cspans[NSPANS]; int currentClip = 0; - const QSpan *end = spans + spanCount; + const QT_FT_Span *end = spans + spanCount; while (spans < end) { - QSpan *clipped = cspans; + QT_FT_Span *clipped = cspans; spans = qt_intersect_spans(fillData->clip, ¤tClip, spans, end, &clipped, NSPANS); // qDebug() << "processed " << spanCount - (end - spans) << "clipped" << clipped-cspans // << "span:" << cspans->x << cspans->y << cspans->len << spans->coverage; @@ -4156,7 +4143,7 @@ static int qt_intersect_spans(QT_FT_Span *&spans, int numSpans, } -static void qt_span_fill_clipRect(int count, const QSpan *spans, +static void qt_span_fill_clipRect(int count, const QT_FT_Span *spans, void *userData) { QSpanData *fillData = reinterpret_cast<QSpanData *>(userData); @@ -4165,7 +4152,7 @@ static void qt_span_fill_clipRect(int count, const QSpan *spans, Q_ASSERT(fillData->clip); Q_ASSERT(!fillData->clip->clipRect.isEmpty()); - QSpan *s = const_cast<QSpan *>(spans); + QT_FT_Span *s = const_cast<QT_FT_Span *>(spans); // hw: check if this const_cast<> is safe!!! count = qt_intersect_spans(s, count, fillData->clip->clipRect); @@ -4173,7 +4160,7 @@ static void qt_span_fill_clipRect(int count, const QSpan *spans, fillData->unclipped_blend(count, s, fillData); } -static void qt_span_clip(int count, const QSpan *spans, void *userData) +static void qt_span_clip(int count, const QT_FT_Span *spans, void *userData) { ClipData *clipData = reinterpret_cast<ClipData *>(userData); @@ -4190,14 +4177,14 @@ static void qt_span_clip(int count, const QSpan *spans, void *userData) newClip->initialize(); int currentClip = 0; - const QSpan *end = spans + count; + const QT_FT_Span *end = spans + count; while (spans < end) { - QSpan *newspans = newClip->m_spans + newClip->count; + QT_FT_Span *newspans = newClip->m_spans + newClip->count; spans = qt_intersect_spans(clipData->oldClip, ¤tClip, spans, end, &newspans, newClip->allocated - newClip->count); newClip->count = newspans - newClip->m_spans; if (spans < end) { - newClip->m_spans = q_check_ptr((QSpan *)realloc(newClip->m_spans, newClip->allocated*2*sizeof(QSpan))); + newClip->m_spans = q_check_ptr((QT_FT_Span *)realloc(newClip->m_spans, newClip->allocated * 2 * sizeof(QT_FT_Span))); newClip->allocated *= 2; } } @@ -4215,7 +4202,7 @@ static void qt_span_clip(int count, const QSpan *spans, void *userData) class QGradientCache { public: - struct CacheInfo : QSpanData::Pinnable + struct CacheInfo { inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) : stops(std::move(s)), opacity(op), interpolationMode(mode) {} @@ -4226,9 +4213,9 @@ public: QGradient::InterpolationMode interpolationMode; }; - typedef QMultiHash<quint64, QSharedPointer<const CacheInfo>> QGradientColorTableHash; + using QGradientColorTableHash = QMultiHash<quint64, std::shared_ptr<const CacheInfo>>; - inline QSharedPointer<const CacheInfo> getBuffer(const QGradient &gradient, int opacity) { + std::shared_ptr<const CacheInfo> getBuffer(const QGradient &gradient, int opacity) { quint64 hash_val = 0; const QGradientStops stops = gradient.stops(); @@ -4258,16 +4245,16 @@ protected: inline void generateGradientColorTable(const QGradient& g, QRgba64 *colorTable, int size, int opacity) const; - QSharedPointer<const CacheInfo> addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { + std::shared_ptr<const CacheInfo> addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { if (cache.size() == maxCacheSize()) { // may remove more than 1, but OK cache.erase(std::next(cache.begin(), QRandomGenerator::global()->bounded(maxCacheSize()))); } - auto cache_entry = QSharedPointer<CacheInfo>::create(gradient.stops(), opacity, gradient.interpolationMode()); + auto cache_entry = std::make_shared<CacheInfo>(gradient.stops(), opacity, gradient.interpolationMode()); generateGradientColorTable(gradient, cache_entry->buffer64, paletteSize(), opacity); for (int i = 0; i < GRADIENT_STOPTABLE_SIZE; ++i) cache_entry->buffer32[i] = cache_entry->buffer64[i].toArgb32(); - return cache.insert(hash_val, cache_entry).value(); + return cache.insert(hash_val, std::move(cache_entry)).value(); } QGradientColorTableHash cache; @@ -4277,7 +4264,7 @@ protected: void QGradientCache::generateGradientColorTable(const QGradient& gradient, QRgba64 *colorTable, int size, int opacity) const { const QGradientStops stops = gradient.stops(); - int stopCount = stops.count(); + int stopCount = stops.size(); Q_ASSERT(stopCount > 0); bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); @@ -4878,7 +4865,7 @@ void dumpClip(int width, int height, const QClipData *clip) ((QClipData *) clip)->spans(); // Force allocation of the spans structure... for (int i = 0; i < clip->count; ++i) { - const QSpan *span = ((QClipData *) clip)->spans() + i; + const QT_FT_Span *span = ((QClipData *) clip)->spans() + i; for (int j = 0; j < span->len; ++j) clipImg.setPixel(span->x + j, span->y, 0xffffff00); x0 = qMin(x0, int(span->x)); |