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; QDirectFbBlitterPlatformPixmap *blitPm = static_cast<QDirectFbBlitterPlatformPixmap *>(pixmap.handle()); 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); if (result != DFB_OK) DirectFBError("QDirectFBBlitter::drawPixmapOpacity()", result); if (m_debugPaint) drawDebugRect(QRect(dRect.x, dRect.y, sRect.w, sRect.h), QColor(Qt::green)); } else { result = m_surface->StretchBlit(m_surface.data(), s, &sRect, &dRect); if (result != DFB_OK) DirectFBError("QDirectFBBlitter::drawPixmapOpacity()", result); if (m_debugPaint) drawDebugRect(QRect(dRect.x, dRect.y, dRect.w, dRect.h), QColor(Qt::red)); } }
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); }
bool QDirectFbBlitter::drawCachedGlyphs(const QPaintEngineState *state, QFontEngine::GlyphFormat glyphFormat, int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, QFontEngine *fontEngine) { void *cacheKey = QDirectFbConvenience::dfbInterface(); QDirectFbTextureGlyphCache *cache = static_cast<QDirectFbTextureGlyphCache *>(fontEngine->glyphCache(cacheKey, glyphFormat, state->transform())); if (!cache) { cache = new QDirectFbTextureGlyphCache(glyphFormat, state->transform()); fontEngine->setGlyphCache(cacheKey, cache); } cache->populate(fontEngine, numGlyphs, glyphs, positions); cache->fillInPendingGlyphs(); if (cache->image().width() == 0 || cache->image().height() == 0) return false; const int margin = fontEngine->glyphMargin(glyphFormat); QVarLengthArray<DFBRectangle, 64> sourceRects(numGlyphs); QVarLengthArray<DFBPoint, 64> destPoints(numGlyphs); int nGlyphs = 0; for (int i=0; i<numGlyphs; ++i) { QFixed subPixelPosition = fontEngine->subPixelPositionForX(positions[i].x); QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition); const QTextureGlyphCache::Coord &c = cache->coords[glyph]; if (c.isNull()) continue; int x = qFloor(positions[i].x) + c.baseLineX - margin; int y = qRound(positions[i].y) - c.baseLineY - margin; // printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n", // c.x, c.y, // c.w, c.h, // c.baseLineX, c.baseLineY, // glyphs[i], // x, y, // positions[i].x.toInt(), positions[i].y.toInt()); sourceRects[nGlyphs].x = c.x; sourceRects[nGlyphs].y = c.y; sourceRects[nGlyphs].w = c.w; sourceRects[nGlyphs].h = c.h; destPoints[nGlyphs].x = x; destPoints[nGlyphs].y = y; ++nGlyphs; } const QColor color = state->pen().color(); m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), color.alpha()); m_surface->SetSrcBlendFunction(m_surface.data(), DSBF_SRCALPHA); m_surface->SetDstBlendFunction(m_surface.data(), DSBF_INVSRCALPHA); int flags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE; if (color.alpha() != 0xff) flags |= DSBLIT_BLEND_COLORALPHA; m_surface->SetBlittingFlags(m_surface.data(), DFBSurfaceBlittingFlags(flags)); const QRasterPaintEngineState *rs = static_cast<const QRasterPaintEngineState*>(state); if (rs->clip && rs->clip->enabled) { Q_ASSERT(rs->clip->hasRectClip); DFBRegion dfbClip; dfbClip.x1 = rs->clip->clipRect.x(); dfbClip.y1 = rs->clip->clipRect.y(); dfbClip.x2 = rs->clip->clipRect.right(); dfbClip.y2 = rs->clip->clipRect.bottom(); m_surface->SetClip(m_surface.data(), &dfbClip); } m_surface->BatchBlit(m_surface.data(), cache->sourceSurface(), sourceRects.constData(), destPoints.constData(), nGlyphs); if (m_debugPaint) { for (int i = 0; i < nGlyphs; ++i) { drawDebugRect(QRect(destPoints[i].x, destPoints[i].y, sourceRects[i].w, sourceRects[i].h), QColor(Qt::yellow)); } } if (rs->clip && rs->clip->enabled) m_surface->SetClip(m_surface.data(), 0); return true; }