void QBlitterPaintEnginePrivate::clipAndDrawPixmap(const QRectF &clip, const QRectF &target, const QPixmap &pm, const QRectF &sr, bool opacity) { Q_Q(QBlitterPaintEngine); QRectF intersectedRect = clip.intersected(target); if (intersectedRect.isEmpty()) return; QRectF source = sr; if (intersectedRect.size() != target.size()) { if (sr.size() == target.size()) { // no resize qreal deltaTop = target.top() - intersectedRect.top(); qreal deltaLeft = target.left() - intersectedRect.left(); qreal deltaBottom = target.bottom() - intersectedRect.bottom(); qreal deltaRight = target.right() - intersectedRect.right(); source.adjust(-deltaLeft, -deltaTop, -deltaRight, -deltaBottom); } else { // resize case qreal hFactor = sr.size().width() / target.size().width(); qreal vFactor = sr.size().height() / target.size().height(); qreal deltaTop = (target.top() - intersectedRect.top()) * vFactor; qreal deltaLeft = (target.left() - intersectedRect.left()) * hFactor; qreal deltaBottom = (target.bottom() - intersectedRect.bottom()) * vFactor; qreal deltaRight = (target.right() - intersectedRect.right()) * hFactor; source.adjust(-deltaLeft, -deltaTop, -deltaRight, -deltaBottom); } } pmData->unmarkRasterOverlay(intersectedRect); if (opacity) pmData->blittable()->drawPixmapOpacity(intersectedRect, pm, source, q->state()->compositionMode(), q->state()->opacity); else pmData->blittable()->drawPixmap(intersectedRect, pm, source); }
void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, const QRectF &srcRect) { QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->width() && data->height()); Q_ASSERT(data->classId() == QPixmapData::BlitterClass); QBlittablePixmapData *blitPm = static_cast<QBlittablePixmapData*>(data); QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blitPm->blittable()); dfbBlitter->unlock(); IDirectFBSurface *s = dfbBlitter->m_surface.data(); DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX; DFBSurfacePorterDuffRule porterDuff = DSPD_SRC; if (pixmap.hasAlpha()) { blittingFlags = DSBLIT_BLEND_ALPHACHANNEL; porterDuff = DSPD_SRC_OVER; } m_surface->SetBlittingFlags(m_surface.data(), DFBSurfaceBlittingFlags(blittingFlags)); m_surface->SetPorterDuff(m_surface.data(), porterDuff); m_surface->SetDstBlendFunction(m_surface.data(), DSBF_INVSRCALPHA); const DFBRectangle sRect = { srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height() }; DFBResult result; if (rect.width() == srcRect.width() && rect.height() == srcRect.height()) result = m_surface->Blit(m_surface.data(), s, &sRect, rect.x(), rect.y()); else { const DFBRectangle dRect = { rect.x(), rect.y(), rect.width(), rect.height() }; result = m_surface->StretchBlit(m_surface.data(), s, &sRect, &dRect); } if (result != DFB_OK) DirectFBError("QDirectFBBlitter::drawPixmap()", result); }
/** * This is borrowing the reference of the QDirectFbBlitter. You may not store this * pointer as a class member but must only use it locally. */ IDirectFBSurface *QDirectFbConvenience::dfbSurfaceForPlatformPixmap(QPixmapData *handle) { QBlittablePixmapData *blittablePmData = static_cast<QBlittablePixmapData *>(handle); if (blittablePmData) { QBlittable *blittable = blittablePmData->blittable(); QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blittable); return dfbBlitter->m_surface.data(); } return 0; }
void QDirectFbBlitter::drawPixmapOpacity(const QRectF &rect, const QPixmap &pixmap, const QRectF &subrect, QPainter::CompositionMode cmode, qreal opacity) { QRect sQRect = subrect.toRect(); QRect dQRect = rect.toRect(); DFBRectangle sRect = { sQRect.x(), sQRect.y(), sQRect.width(), sQRect.height() }; DFBRectangle dRect = { dQRect.x(), dQRect.y(), dQRect.width(), dQRect.height() }; DFBResult result; // skip if dst too small if ((dRect.w <= 0) || (dRect.h <= 0)) return; // correct roundings if needed if (sRect.w <= 0) sRect.w = 1; if (sRect.h <= 0) sRect.h = 1; QBlittablePixmapData *blitPm = static_cast<QBlittablePixmapData*>(pixmap.pixmapData()); QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blitPm->blittable()); dfbBlitter->unlock(); IDirectFBSurface *s = dfbBlitter->m_surface.data(); DFBSurfaceBlittingFlags blittingFlags = DFBSurfaceBlittingFlags(DSBLIT_BLEND_ALPHACHANNEL); DFBSurfacePorterDuffRule porterDuff = (cmode == QPainter::CompositionMode_SourceOver) ? DSPD_SRC_OVER : DSPD_SRC; if (opacity != 1.0) { blittingFlags = DFBSurfaceBlittingFlags(blittingFlags | DSBLIT_BLEND_COLORALPHA | (m_premult ? DSBLIT_SRC_PREMULTCOLOR : 0)); m_surface->SetColor(m_surface.data(), 0xff, 0xff, 0xff, (u8) (opacity * 255.0)); } m_surface->SetBlittingFlags(m_surface.data(), DFBSurfaceBlittingFlags(blittingFlags)); m_surface->SetPorterDuff(m_surface.data(), porterDuff); if (cmode == QPainter::CompositionMode_SourceOver) m_surface->SetDstBlendFunction(m_surface.data(), DSBF_INVSRCALPHA); if ((sRect.w == dRect.w) && (sRect.h == dRect.h)) result = m_surface->Blit(m_surface.data(), s, &sRect, dRect.x, dRect.y); else result = m_surface->StretchBlit(m_surface.data(), s, &sRect, &dRect); if (result != DFB_OK) DirectFBError("QDirectFBBlitter::drawPixmapExtended()", result); }
void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &color, bool alpha) { Q_Q(QBlitterPaintEngine); pmData->unmarkRasterOverlay(rect); QRectF targetRect = rect; if (hasXForm) targetRect = q->state()->matrix.mapRect(rect); const QClipData *clipData = clip(); if (clipData) { if (clipData->hasRectClip) { unlock(); if (alpha) pmData->blittable()->alphaFillRect(targetRect & clipData->clipRect, color, q->state()->compositionMode()); else pmData->blittable()->fillRect(targetRect & clipData->clipRect, color); } else if (clipData->hasRegionClip) { QVector<QRect> rects = clipData->clipRegion.rects(); for (int i = 0; i < rects.size(); ++i) { QRect intersectRect = rects.at(i).intersected(targetRect.toRect()); if (!intersectRect.isEmpty()) { unlock(); if (alpha) pmData->blittable()->alphaFillRect(intersectRect, color, q->state()->compositionMode()); else pmData->blittable()->fillRect(intersectRect, color); } } } } else { if (targetRect.x() >= 0 && targetRect.y() >= 0 && targetRect.width() <= q->paintDevice()->width() && targetRect.height() <= q->paintDevice()->height()) { unlock(); if (alpha) pmData->blittable()->alphaFillRect(targetRect, color, q->state()->compositionMode()); else pmData->blittable()->fillRect(targetRect, color); } else { QRectF deviceRect(0, 0, q->paintDevice()->width(), q->paintDevice()->height()); unlock(); if (alpha) pmData->blittable()->alphaFillRect(deviceRect & targetRect, color, q->state()->compositionMode()); else pmData->blittable()->fillRect(deviceRect & targetRect, color); } } }
inline void QBlitterPaintEnginePrivate::unlock() { pmData->blittable()->unlock(); }
inline void QBlitterPaintEnginePrivate::lock() { if (!pmData->blittable()->isLocked()) rasterBuffer->prepare(pmData->buffer()); }