502 lines
18 KiB
C++
502 lines
18 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
** Contact: https://www.qt.io/licensing/
|
|
**
|
|
** This file is part of the plugins of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:LGPL$
|
|
** Commercial License Usage
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
** accordance with the commercial license agreement provided with the
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
|
**
|
|
** GNU Lesser General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
** General Public License version 3 as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
|
** packaging of this file. Please review the following information to
|
|
** ensure the GNU Lesser General Public License version 3 requirements
|
|
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 2.0 or (at your option) the GNU General
|
|
** Public license version 3 or any later version approved by the KDE Free
|
|
** Qt Foundation. The licenses are as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
|
** included in the packaging of this file. Please review the following
|
|
** information to ensure the GNU General Public License requirements will
|
|
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
|
** https://www.gnu.org/licenses/gpl-3.0.html.
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include "qdirectfbblitter.h"
|
|
#include "qdirectfbconvenience.h"
|
|
|
|
#include <QtGui/private/qpixmap_blitter_p.h>
|
|
|
|
#include <QDebug>
|
|
#include <QFile>
|
|
|
|
#include <directfb.h>
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
static QBlittable::Capabilities dfb_blitter_capabilities()
|
|
{
|
|
return QBlittable::Capabilities(QBlittable::SolidRectCapability
|
|
|QBlittable::SourcePixmapCapability
|
|
|QBlittable::SourceOverPixmapCapability
|
|
|QBlittable::SourceOverScaledPixmapCapability
|
|
|QBlittable::AlphaFillRectCapability
|
|
|QBlittable::OpacityPixmapCapability
|
|
|QBlittable::DrawScaledCachedGlyphsCapability
|
|
);
|
|
}
|
|
|
|
QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, IDirectFBSurface *surface)
|
|
: QBlittable(rect, dfb_blitter_capabilities())
|
|
, m_surface(surface)
|
|
, m_debugPaint(false)
|
|
{
|
|
m_surface->AddRef(m_surface.data());
|
|
|
|
DFBSurfaceCapabilities surfaceCaps;
|
|
m_surface->GetCapabilities(m_surface.data(), &surfaceCaps);
|
|
m_premult = (surfaceCaps & DSCAPS_PREMULTIPLIED);
|
|
if (qEnvironmentVariableIntValue("QT_DIRECTFB_BLITTER_DEBUGPAINT"))
|
|
m_debugPaint = true;
|
|
}
|
|
|
|
QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, bool alpha)
|
|
: QBlittable(rect, dfb_blitter_capabilities())
|
|
, m_premult(false)
|
|
, m_debugPaint(false)
|
|
{
|
|
DFBSurfaceDescription surfaceDesc;
|
|
memset(&surfaceDesc,0,sizeof(DFBSurfaceDescription));
|
|
surfaceDesc.width = rect.width();
|
|
surfaceDesc.height = rect.height();
|
|
|
|
// force alpha format to get AlphaFillRectCapability and ExtendedPixmapCapability support
|
|
alpha = true;
|
|
|
|
if (alpha) {
|
|
m_premult = true;
|
|
surfaceDesc.caps = DSCAPS_PREMULTIPLIED;
|
|
surfaceDesc.pixelformat = QDirectFbBlitter::alphaPixmapFormat();
|
|
surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT);
|
|
} else {
|
|
surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT);
|
|
surfaceDesc.pixelformat = QDirectFbBlitter::pixmapFormat();
|
|
}
|
|
|
|
if (qEnvironmentVariableIntValue("QT_DIRECTFB_BLITTER_DEBUGPAINT"))
|
|
m_debugPaint = true;
|
|
|
|
IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
|
|
dfb->CreateSurface(dfb , &surfaceDesc, m_surface.outPtr());
|
|
m_surface->Clear(m_surface.data(), 0, 0, 0, 0);
|
|
}
|
|
|
|
QDirectFbBlitter::~QDirectFbBlitter()
|
|
{
|
|
unlock();
|
|
}
|
|
|
|
DFBSurfacePixelFormat QDirectFbBlitter::alphaPixmapFormat()
|
|
{
|
|
return DSPF_ARGB;
|
|
}
|
|
|
|
DFBSurfacePixelFormat QDirectFbBlitter::pixmapFormat()
|
|
{
|
|
return DSPF_RGB32;
|
|
}
|
|
|
|
DFBSurfacePixelFormat QDirectFbBlitter::selectPixmapFormat(bool withAlpha)
|
|
{
|
|
return withAlpha ? alphaPixmapFormat() : pixmapFormat();
|
|
}
|
|
|
|
void QDirectFbBlitter::fillRect(const QRectF &rect, const QColor &color)
|
|
{
|
|
alphaFillRect(rect, color, QPainter::CompositionMode_Source);
|
|
}
|
|
|
|
void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, const QRectF &srcRect)
|
|
{
|
|
drawPixmapOpacity(rect, pixmap, srcRect, QPainter::CompositionMode_SourceOver, 1.0);
|
|
}
|
|
|
|
void QDirectFbBlitter::alphaFillRect(const QRectF &rect, const QColor &color, QPainter::CompositionMode cmode)
|
|
{
|
|
int x, y, w, h;
|
|
DFBResult result;
|
|
|
|
// check parameters
|
|
rect.toRect().getRect(&x, &y ,&w, &h);
|
|
if ((w <= 0) || (h <= 0)) return;
|
|
|
|
if ((cmode == QPainter::CompositionMode_Source) || (color.alpha() == 255)) {
|
|
// CompositionMode_Source case or CompositionMode_SourceOver with opaque color
|
|
|
|
m_surface->SetDrawingFlags(m_surface.data(),
|
|
DFBSurfaceDrawingFlags(m_premult ? (DSDRAW_NOFX | DSDRAW_SRC_PREMULTIPLY) : DSDRAW_NOFX));
|
|
m_surface->SetPorterDuff(m_surface.data(), DSPD_SRC);
|
|
|
|
} else {
|
|
// CompositionMode_SourceOver case
|
|
|
|
// check if operation is useless
|
|
if (color.alpha() == 0)
|
|
return;
|
|
|
|
m_surface->SetDrawingFlags(m_surface.data(),
|
|
DFBSurfaceDrawingFlags(m_premult ? (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY) : DSDRAW_BLEND));
|
|
m_surface->SetPorterDuff(m_surface.data(), DSPD_SRC_OVER);
|
|
}
|
|
|
|
// set color
|
|
m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), color.alpha());
|
|
|
|
// perform fill
|
|
result = m_surface->FillRectangle(m_surface.data(), x, y, w, h);
|
|
if (result != DFB_OK)
|
|
DirectFBError("QDirectFBBlitter::alphaFillRect()", result);
|
|
if (m_debugPaint)
|
|
drawDebugRect(QRect(x, y, w, h), QColor(Qt::blue));
|
|
}
|
|
|
|
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));
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
QImage *QDirectFbBlitter::doLock()
|
|
{
|
|
Q_ASSERT(m_surface);
|
|
Q_ASSERT(size().isValid());
|
|
|
|
void *mem;
|
|
int bpl;
|
|
const DFBResult result = m_surface->Lock(m_surface.data(), DFBSurfaceLockFlags(DSLF_WRITE|DSLF_READ), static_cast<void**>(&mem), &bpl);
|
|
if (result == DFB_OK) {
|
|
DFBSurfacePixelFormat dfbFormat;
|
|
DFBSurfaceCapabilities dfbCaps;
|
|
m_surface->GetPixelFormat(m_surface.data(), &dfbFormat);
|
|
m_surface->GetCapabilities(m_surface.data(), &dfbCaps);
|
|
QImage::Format format = QDirectFbConvenience::imageFormatFromSurfaceFormat(dfbFormat, dfbCaps);
|
|
int w, h;
|
|
m_surface->GetSize(m_surface.data(), &w, &h);
|
|
m_image = QImage(static_cast<uchar *>(mem),w,h,bpl,format);
|
|
} else {
|
|
DirectFBError("Failed to lock image", result);
|
|
}
|
|
|
|
return &m_image;
|
|
}
|
|
|
|
bool QDirectFbBlitterPlatformPixmap::fromDataBufferDescription(const DFBDataBufferDescription &dataBufferDescription)
|
|
{
|
|
DFBResult result;
|
|
IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
|
|
|
|
// Create a data buffer
|
|
QDirectFBPointer<IDirectFBDataBuffer> dataBuffer;
|
|
result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, dataBuffer.outPtr());
|
|
if (result != DFB_OK) {
|
|
DirectFBError(QDFB_PRETTY, result);
|
|
return false;
|
|
}
|
|
|
|
// Create the image provider
|
|
QDirectFBPointer<IDirectFBImageProvider> provider;
|
|
result = dataBuffer->CreateImageProvider(dataBuffer.data(), provider.outPtr());
|
|
if (result != DFB_OK) {
|
|
DirectFBError(QDFB_PRETTY, result);
|
|
return false;
|
|
}
|
|
|
|
// Extract image information
|
|
DFBImageDescription imageDescription;
|
|
result = provider->GetImageDescription(provider.data(), &imageDescription);
|
|
if (result != DFB_OK) {
|
|
DirectFBError(QDFB_PRETTY, result);
|
|
return false;
|
|
}
|
|
|
|
// Can we handle this directlu?
|
|
if (imageDescription.caps & DICAPS_COLORKEY)
|
|
return false;
|
|
|
|
DFBSurfaceDescription surfaceDescription;
|
|
result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription);
|
|
if (result != DFB_OK) {
|
|
DirectFBError(QDFB_PRETTY, result);
|
|
return false;
|
|
}
|
|
|
|
m_alpha = imageDescription.caps & DICAPS_ALPHACHANNEL;
|
|
resize(surfaceDescription.width, surfaceDescription.height);
|
|
// TODO: FIXME; update d
|
|
|
|
|
|
result = provider->RenderTo(provider.data(), dfbBlitter()->dfbSurface(), 0);
|
|
if (result != DFB_OK) {
|
|
DirectFBError(QDFB_PRETTY, result);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool QDirectFbBlitterPlatformPixmap::fromFile(const QString &filename, const char *format,
|
|
Qt::ImageConversionFlags flags)
|
|
{
|
|
// If we can't find the file, pass it on to the base class as it is
|
|
// trying harder by appending various extensions to the path.
|
|
if (!QFile::exists(filename))
|
|
return QBlittablePlatformPixmap::fromFile(filename, format, flags);
|
|
|
|
// Stop if there is a requirement for colors
|
|
if (flags != Qt::AutoColor)
|
|
return QBlittablePlatformPixmap::fromFile(filename, format, flags);
|
|
|
|
// Deal with resources
|
|
if (filename.startsWith(QLatin1Char(':')))
|
|
return QBlittablePlatformPixmap::fromFile(filename, format, flags);
|
|
|
|
// Try to use directfb to load it.
|
|
DFBDataBufferDescription description;
|
|
description.flags = DBDESC_FILE;
|
|
const QByteArray fileNameData = filename.toLocal8Bit();
|
|
description.file = fileNameData.constData();
|
|
if (fromDataBufferDescription(description))
|
|
return true;
|
|
|
|
// Fallback
|
|
return QBlittablePlatformPixmap::fromFile(filename, format, flags);
|
|
}
|
|
|
|
void QDirectFbBlitter::doUnlock()
|
|
{
|
|
m_surface->Unlock(m_surface.data());
|
|
}
|
|
|
|
void QDirectFbBlitter::drawDebugRect(const QRect &rect, const QColor &color)
|
|
{
|
|
int x, y, w, h;
|
|
DFBResult result;
|
|
|
|
// check parameters
|
|
rect.getRect(&x, &y ,&w, &h);
|
|
if ((w <= 0) || (h <= 0)) return;
|
|
|
|
m_surface->SetDrawingFlags(m_surface.data(),
|
|
DFBSurfaceDrawingFlags(m_premult ? (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY) : DSDRAW_BLEND));
|
|
m_surface->SetPorterDuff(m_surface.data(), DSPD_SRC_OVER);
|
|
|
|
// set color
|
|
m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), 120);
|
|
|
|
result = m_surface->DrawLine(m_surface.data(), x, y, x + w-1, y);
|
|
if (result != DFB_OK)
|
|
DirectFBError("QDirectFBBlitter::drawDebugRect()", result);
|
|
result = m_surface->DrawLine(m_surface.data(), x + w-1, y, x + w-1, y + h-1);
|
|
if (result != DFB_OK)
|
|
DirectFBError("QDirectFBBlitter::drawDebugRect()", result);
|
|
result = m_surface->DrawLine(m_surface.data(), x + w-1, y + h-1, x, y + h-1);
|
|
if (result != DFB_OK)
|
|
DirectFBError("QDirectFBBlitter::drawDebugRect()", result);
|
|
result = m_surface->DrawLine(m_surface.data(), x, y + h-1, x, y);
|
|
if (result != DFB_OK)
|
|
DirectFBError("QDirectFBBlitter::drawDebugRect()", result);
|
|
|
|
m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), 10);
|
|
result = m_surface->FillRectangle(m_surface.data(), x, y, w, h);
|
|
if (result != DFB_OK)
|
|
DirectFBError("QDirectFBBlitter::drawDebugRect()", result);
|
|
}
|
|
|
|
void QDirectFbTextureGlyphCache::resizeTextureData(int width, int height)
|
|
{
|
|
m_surface.reset();;
|
|
QImageTextureGlyphCache::resizeTextureData(width, height);
|
|
}
|
|
|
|
IDirectFBSurface *QDirectFbTextureGlyphCache::sourceSurface()
|
|
{
|
|
if (m_surface.isNull()) {
|
|
const QImage &source = image();
|
|
DFBSurfaceDescription desc;
|
|
memset(&desc, 0, sizeof(desc));
|
|
desc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_PREALLOCATED | DSDESC_CAPS);
|
|
desc.width = source.width();
|
|
desc.height = source.height();
|
|
desc.caps = DSCAPS_SYSTEMONLY;
|
|
|
|
switch (source.format()) {
|
|
case QImage::Format_Mono:
|
|
desc.pixelformat = DSPF_A1;
|
|
break;
|
|
case QImage::Format_Alpha8:
|
|
desc.pixelformat = DSPF_A8;
|
|
break;
|
|
default:
|
|
qFatal("QDirectFBTextureGlyphCache: Unsupported source texture image format.");
|
|
break;
|
|
}
|
|
|
|
desc.preallocated[0].data = const_cast<void*>(static_cast<const void*>(source.bits()));
|
|
desc.preallocated[0].pitch = source.bytesPerLine();
|
|
desc.preallocated[1].data = 0;
|
|
desc.preallocated[1].pitch = 0;
|
|
|
|
IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
|
|
dfb->CreateSurface(dfb , &desc, m_surface.outPtr());
|
|
}
|
|
return m_surface.data();
|
|
}
|
|
|
|
QT_END_NAMESPACE
|