8#include <QtGui/private/qpixmap_blitter_p.h>
19 return QBlittable::Capabilities(QBlittable::SolidRectCapability
20 |QBlittable::SourcePixmapCapability
21 |QBlittable::SourceOverPixmapCapability
22 |QBlittable::SourceOverScaledPixmapCapability
23 |QBlittable::AlphaFillRectCapability
24 |QBlittable::OpacityPixmapCapability
25 |QBlittable::DrawScaledCachedGlyphsCapability
34 m_surface->AddRef(m_surface.data());
36 DFBSurfaceCapabilities surfaceCaps;
37 m_surface->GetCapabilities(m_surface.data(), &surfaceCaps);
38 m_premult = (surfaceCaps & DSCAPS_PREMULTIPLIED);
39 if (qEnvironmentVariableIntValue(
"QT_DIRECTFB_BLITTER_DEBUGPAINT"))
48 DFBSurfaceDescription surfaceDesc;
49 memset(&surfaceDesc,0,
sizeof(DFBSurfaceDescription));
50 surfaceDesc.width = rect.width();
51 surfaceDesc.height = rect.height();
58 surfaceDesc.caps = DSCAPS_PREMULTIPLIED;
59 surfaceDesc.pixelformat = QDirectFbBlitter::alphaPixmapFormat();
60 surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT);
62 surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT);
63 surfaceDesc.pixelformat = QDirectFbBlitter::pixmapFormat();
66 if (qEnvironmentVariableIntValue(
"QT_DIRECTFB_BLITTER_DEBUGPAINT"))
69 IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
70 dfb->CreateSurface(dfb , &surfaceDesc, m_surface.outPtr());
71 m_surface->Clear(m_surface.data(), 0, 0, 0, 0);
91 return withAlpha ? alphaPixmapFormat() : pixmapFormat();
96 alphaFillRect(rect, color, QPainter::CompositionMode_Source);
101 drawPixmapOpacity(rect, pixmap, srcRect, QPainter::CompositionMode_SourceOver, 1.0);
110 rect.toRect().getRect(&x, &y ,&w, &h);
111 if ((w <= 0) || (h <= 0))
return;
113 if ((cmode == QPainter::CompositionMode_Source) || (color.alpha() == 255)) {
116 m_surface->SetDrawingFlags(m_surface.data(),
117 DFBSurfaceDrawingFlags(m_premult ? (DSDRAW_NOFX | DSDRAW_SRC_PREMULTIPLY) : DSDRAW_NOFX));
118 m_surface->SetPorterDuff(m_surface.data(), DSPD_SRC);
124 if (color.alpha() == 0)
127 m_surface->SetDrawingFlags(m_surface.data(),
128 DFBSurfaceDrawingFlags(m_premult ? (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY) : DSDRAW_BLEND));
129 m_surface->SetPorterDuff(m_surface.data(), DSPD_SRC_OVER);
133 m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), color.alpha());
136 result = m_surface->FillRectangle(m_surface.data(), x, y, w, h);
137 if (result != DFB_OK)
138 DirectFBError(
"QDirectFBBlitter::alphaFillRect()", result);
140 drawDebugRect(QRect(x, y, w, h), QColor(Qt::blue));
145 QRect sQRect = subrect.toRect();
146 QRect dQRect = rect.toRect();
147 DFBRectangle sRect(sQRect.x(), sQRect.y(), sQRect.width(), sQRect.height());
148 DFBRectangle dRect(dQRect.x(), dQRect.y(), dQRect.width(), dQRect.height());
152 if ((dRect.w <= 0) || (dRect.h <= 0))
return;
155 if (sRect.w <= 0) sRect.w = 1;
156 if (sRect.h <= 0) sRect.h = 1;
160 dfbBlitter->unlock();
162 IDirectFBSurface *s = dfbBlitter->m_surface.data();
164 DFBSurfaceBlittingFlags blittingFlags = DFBSurfaceBlittingFlags(DSBLIT_BLEND_ALPHACHANNEL);
165 DFBSurfacePorterDuffRule porterDuff = (cmode == QPainter::CompositionMode_SourceOver) ? DSPD_SRC_OVER : DSPD_SRC;
169 blittingFlags = DFBSurfaceBlittingFlags(blittingFlags | DSBLIT_BLEND_COLORALPHA | (m_premult ? DSBLIT_SRC_PREMULTCOLOR : 0));
170 m_surface->SetColor(m_surface.data(), 0xff, 0xff, 0xff, (u8) (opacity * 255.0));
173 m_surface->SetBlittingFlags(m_surface.data(), DFBSurfaceBlittingFlags(blittingFlags));
174 m_surface->SetPorterDuff(m_surface.data(), porterDuff);
176 if (cmode == QPainter::CompositionMode_SourceOver)
177 m_surface->SetDstBlendFunction(m_surface.data(), DSBF_INVSRCALPHA);
179 if ((sRect.w == dRect.w) && (sRect.h == dRect.h)) {
180 result = m_surface->Blit(m_surface.data(), s, &sRect, dRect.x, dRect.y);
181 if (result != DFB_OK)
182 DirectFBError(
"QDirectFBBlitter::drawPixmapOpacity()", result);
184 drawDebugRect(QRect(dRect.x, dRect.y, sRect.w, sRect.h), QColor(Qt::green));
186 result = m_surface->StretchBlit(m_surface.data(), s, &sRect, &dRect);
187 if (result != DFB_OK)
188 DirectFBError(
"QDirectFBBlitter::drawPixmapOpacity()", result);
190 drawDebugRect(QRect(dRect.x, dRect.y, dRect.w, dRect.h), QColor(Qt::red));
194bool QDirectFbBlitter::
drawCachedGlyphs(
const QPaintEngineState *state, QFontEngine::GlyphFormat glyphFormat,
int numGlyphs,
const glyph_t *glyphs,
const QFixedPoint *positions, QFontEngine *fontEngine)
196 void *cacheKey = QDirectFbConvenience::dfbInterface();
202 fontEngine->setGlyphCache(cacheKey, cache);
205 cache->populate(fontEngine, numGlyphs, glyphs, positions);
206 cache->fillInPendingGlyphs();
208 if (cache->image().width() == 0 || cache->image().height() == 0)
211 const int margin = fontEngine->glyphMargin(glyphFormat);
213 QVarLengthArray<DFBRectangle, 64> sourceRects(numGlyphs);
214 QVarLengthArray<DFBPoint, 64> destPoints(numGlyphs);
217 for (
int i=0; i<numGlyphs; ++i) {
219 QFixed subPixelPosition = fontEngine->subPixelPositionForX(positions[i].x);
220 QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], QFixedPoint(subPixelPosition, 0));
221 const QTextureGlyphCache::Coord &c = cache->coords[glyph];
225 int x = qFloor(positions[i].x) + c.baseLineX - margin;
226 int y = qRound(positions[i].y) - c.baseLineY - margin;
236 sourceRects[nGlyphs].x = c.x;
237 sourceRects[nGlyphs].y = c.y;
238 sourceRects[nGlyphs].w = c.w;
239 sourceRects[nGlyphs].h = c.h;
240 destPoints[nGlyphs].x = x;
241 destPoints[nGlyphs].y = y;
245 const QColor color = state->pen().color();
246 m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), color.alpha());
248 m_surface->SetSrcBlendFunction(m_surface.data(), DSBF_SRCALPHA);
249 m_surface->SetDstBlendFunction(m_surface.data(), DSBF_INVSRCALPHA);
251 int flags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE;
252 if (color.alpha() != 0xff)
253 flags |= DSBLIT_BLEND_COLORALPHA;
254 m_surface->SetBlittingFlags(m_surface.data(), DFBSurfaceBlittingFlags(flags));
256 const QRasterPaintEngineState *rs =
static_cast<
const QRasterPaintEngineState*>(state);
257 if (rs->clip && rs->clip->enabled) {
258 Q_ASSERT(rs->clip->hasRectClip);
260 dfbClip.x1 = rs->clip->clipRect.x();
261 dfbClip.y1 = rs->clip->clipRect.y();
262 dfbClip.x2 = rs->clip->clipRect.right();
263 dfbClip.y2 = rs->clip->clipRect.bottom();
264 m_surface->SetClip(m_surface.data(), &dfbClip);
267 m_surface->BatchBlit(m_surface.data(), cache->sourceSurface(), sourceRects.constData(), destPoints.constData(), nGlyphs);
270 for (
int i = 0; i < nGlyphs; ++i) {
271 drawDebugRect(QRect(destPoints[i].x, destPoints[i].y, sourceRects[i].w, sourceRects[i].h), QColor(Qt::yellow));
275 if (rs->clip && rs->clip->enabled)
276 m_surface->SetClip(m_surface.data(), 0);
283 Q_ASSERT(size().isValid());
287 const DFBResult result = m_surface->Lock(m_surface.data(), DFBSurfaceLockFlags(DSLF_WRITE|DSLF_READ),
static_cast<
void**>(&mem), &bpl);
288 if (result == DFB_OK) {
289 DFBSurfacePixelFormat dfbFormat;
290 DFBSurfaceCapabilities dfbCaps;
291 m_surface->GetPixelFormat(m_surface.data(), &dfbFormat);
292 m_surface->GetCapabilities(m_surface.data(), &dfbCaps);
293 QImage::Format format = QDirectFbConvenience::imageFormatFromSurfaceFormat(dfbFormat, dfbCaps);
295 m_surface->GetSize(m_surface.data(), &w, &h);
296 m_image = QImage(
static_cast<uchar *>(mem),w,h,bpl,format);
298 DirectFBError(
"Failed to lock image", result);
307 IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
310 QDirectFBPointer<IDirectFBDataBuffer> dataBuffer;
311 result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, dataBuffer.outPtr());
312 if (result != DFB_OK) {
318 QDirectFBPointer<IDirectFBImageProvider> provider;
319 result = dataBuffer->CreateImageProvider(dataBuffer.data(), provider.outPtr());
320 if (result != DFB_OK) {
326 DFBImageDescription imageDescription;
327 result = provider->GetImageDescription(provider.data(), &imageDescription);
328 if (result != DFB_OK) {
334 if (imageDescription.caps & DICAPS_COLORKEY)
337 DFBSurfaceDescription surfaceDescription;
338 result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription);
339 if (result != DFB_OK) {
344 m_alpha = imageDescription.caps & DICAPS_ALPHACHANNEL;
345 resize(surfaceDescription.width, surfaceDescription.height);
349 result = provider->RenderTo(provider.data(),
dfbBlitter()->dfbSurface(), 0);
350 if (result != DFB_OK) {
359 Qt::ImageConversionFlags flags)
363 if (!QFile::exists(filename))
364 return QBlittablePlatformPixmap::fromFile(filename, format, flags);
367 if (flags != Qt::AutoColor)
368 return QBlittablePlatformPixmap::fromFile(filename, format, flags);
371 if (filename.startsWith(u':'))
372 return QBlittablePlatformPixmap::fromFile(filename, format, flags);
375 DFBDataBufferDescription description;
376 description.flags = DBDESC_FILE;
377 const QByteArray fileNameData = filename.toLocal8Bit();
378 description.file = fileNameData.constData();
379 if (fromDataBufferDescription(description))
383 return QBlittablePlatformPixmap::fromFile(filename, format, flags);
388 m_surface->Unlock(m_surface.data());
397 rect.getRect(&x, &y ,&w, &h);
398 if ((w <= 0) || (h <= 0))
return;
400 m_surface->SetDrawingFlags(m_surface.data(),
401 DFBSurfaceDrawingFlags(m_premult ? (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY) : DSDRAW_BLEND));
402 m_surface->SetPorterDuff(m_surface.data(), DSPD_SRC_OVER);
405 m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), 120);
407 result = m_surface->DrawLine(m_surface.data(), x, y, x + w-1, y);
408 if (result != DFB_OK)
409 DirectFBError(
"QDirectFBBlitter::drawDebugRect()", result);
410 result = m_surface->DrawLine(m_surface.data(), x + w-1, y, x + w-1, y + h-1);
411 if (result != DFB_OK)
412 DirectFBError(
"QDirectFBBlitter::drawDebugRect()", result);
413 result = m_surface->DrawLine(m_surface.data(), x + w-1, y + h-1, x, y + h-1);
414 if (result != DFB_OK)
415 DirectFBError(
"QDirectFBBlitter::drawDebugRect()", result);
416 result = m_surface->DrawLine(m_surface.data(), x, y + h-1, x, y);
417 if (result != DFB_OK)
418 DirectFBError(
"QDirectFBBlitter::drawDebugRect()", result);
420 m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), 10);
421 result = m_surface->FillRectangle(m_surface.data(), x, y, w, h);
422 if (result != DFB_OK)
423 DirectFBError(
"QDirectFBBlitter::drawDebugRect()", result);
429 QImageTextureGlyphCache::resizeTextureData(width, height);
434 if (m_surface.isNull()) {
435 const QImage &source = image();
436 DFBSurfaceDescription desc;
437 memset(&desc, 0,
sizeof(desc));
438 desc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_PREALLOCATED | DSDESC_CAPS);
439 desc.width = source.width();
440 desc.height = source.height();
441 desc.caps = DSCAPS_SYSTEMONLY;
443 switch (source.format()) {
444 case QImage::Format_Mono:
445 desc.pixelformat = DSPF_A1;
447 case QImage::Format_Alpha8:
448 desc.pixelformat = DSPF_A8;
451 qFatal(
"QDirectFBTextureGlyphCache: Unsupported source texture image format.");
455 desc.preallocated[0].data =
const_cast<
void*>(
static_cast<
const void*>(source.bits()));
456 desc.preallocated[0].pitch = source.bytesPerLine();
457 desc.preallocated[1].data = 0;
458 desc.preallocated[1].pitch = 0;
460 IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
461 dfb->CreateSurface(dfb , &desc, m_surface.outPtr());
463 return m_surface.data();
virtual ~QDirectFbBlitter()
bool drawCachedGlyphs(const QPaintEngineState *state, QFontEngine::GlyphFormat glyphFormat, int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, QFontEngine *fontEngine) override
void alphaFillRect(const QRectF &rect, const QColor &color, QPainter::CompositionMode cmode) override
QDirectFbBlitter(const QSize &size, bool alpha)
QDirectFbBlitter(const QSize &size, IDirectFBSurface *surface)
QImage * doLock() override
void drawPixmapOpacity(const QRectF &rect, const QPixmap &pixmap, const QRectF &subrect, QPainter::CompositionMode cmode, qreal opacity) override
void fillRect(const QRectF &rect, const QColor &color) override
void drawPixmap(const QRectF &rect, const QPixmap &pixmap, const QRectF &subrect) override
void resizeTextureData(int width, int height) override
IDirectFBSurface * sourceSurface()
static QT_BEGIN_NAMESPACE QBlittable::Capabilities dfb_blitter_capabilities()