示例#1
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;

    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));
    }
}
示例#2
0
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);
}
示例#3
0
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;
}