basic blitting implementation
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41274 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
11ea1abfa0
commit
5942996c94
@ -203,6 +203,10 @@ private:
|
|||||||
void DoDrawSubBitmap(const wxBitmap &bmp,
|
void DoDrawSubBitmap(const wxBitmap &bmp,
|
||||||
wxCoord x, wxCoord y, wxCoord w, wxCoord h,
|
wxCoord x, wxCoord y, wxCoord w, wxCoord h,
|
||||||
wxCoord destx, wxCoord desty, int rop, bool useMask);
|
wxCoord destx, wxCoord desty, int rop, bool useMask);
|
||||||
|
bool DoBlitFromSurface(const wxIDirectFBSurfacePtr& src,
|
||||||
|
wxCoord srcx, wxCoord srcy,
|
||||||
|
wxCoord w, wxCoord h,
|
||||||
|
wxCoord dstx, wxCoord dsty);
|
||||||
|
|
||||||
// selects colour into surface's state
|
// selects colour into surface's state
|
||||||
void SelectColour(const wxColour& clr);
|
void SelectColour(const wxColour& clr);
|
||||||
|
@ -22,6 +22,13 @@ public:
|
|||||||
|
|
||||||
virtual void SelectObject(const wxBitmap& bitmap);
|
virtual void SelectObject(const wxBitmap& bitmap);
|
||||||
|
|
||||||
|
// implementation from now on:
|
||||||
|
|
||||||
|
wxBitmap GetSelectedObject() const { return m_bmp; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxBitmap m_bmp;
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxMemoryDC)
|
DECLARE_DYNAMIC_CLASS(wxMemoryDC)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -274,6 +274,14 @@ struct wxIDirectFBSurface : public wxDfbWrapper<IDirectFBSurface>
|
|||||||
int x, int y)
|
int x, int y)
|
||||||
{ return Check(m_ptr->Blit(m_ptr, source, source_rect, x, y)); }
|
{ return Check(m_ptr->Blit(m_ptr, source, source_rect, x, y)); }
|
||||||
|
|
||||||
|
bool StretchBlit(const wxIDirectFBSurfacePtr& source,
|
||||||
|
const DFBRectangle *source_rect,
|
||||||
|
const DFBRectangle *dest_rect)
|
||||||
|
{
|
||||||
|
return Check(m_ptr->StretchBlit(m_ptr, source->GetRaw(),
|
||||||
|
source_rect, dest_rect));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Returns bit depth used by the surface or -1 on error
|
/// Returns bit depth used by the surface or -1 on error
|
||||||
int GetDepth();
|
int GetDepth();
|
||||||
|
177
src/dfb/dc.cpp
177
src/dfb/dc.cpp
@ -391,7 +391,10 @@ void wxDC::SetLogicalFunction(int function)
|
|||||||
{
|
{
|
||||||
wxCHECK_RET( Ok(), wxT("invalid dc") );
|
wxCHECK_RET( Ok(), wxT("invalid dc") );
|
||||||
|
|
||||||
wxFAIL_MSG( _T("SetLogicalFunction not implemented") );
|
// NB: we could also support XOR, but for blitting only (via DSBLIT_XOR);
|
||||||
|
// and possibly others via SetSrc/DstBlendFunction()
|
||||||
|
wxASSERT_MSG( function == wxCOPY,
|
||||||
|
_T("only wxCOPY logical function supported") );
|
||||||
|
|
||||||
m_logicalFunction = function;
|
m_logicalFunction = function;
|
||||||
}
|
}
|
||||||
@ -651,17 +654,21 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
|||||||
int rop, bool useMask,
|
int rop, bool useMask,
|
||||||
wxCoord xsrcMask, wxCoord ysrcMask)
|
wxCoord xsrcMask, wxCoord ysrcMask)
|
||||||
{
|
{
|
||||||
#warning "FIXME"
|
wxCHECK_MSG( Ok(), false, _T("invalid dc") );
|
||||||
return false;
|
wxCHECK_MSG( source, false, _T("invalid source dc") );
|
||||||
#if 0
|
|
||||||
wxCHECK_MSG( Ok(), false, wxT("invalid dc") );
|
// NB: we could also support XOR here (via DSBLIT_XOR)
|
||||||
wxCHECK_MSG( source, false, wxT("invalid source dc") );
|
// and possibly others via SetSrc/DstBlendFunction()
|
||||||
|
wxCHECK_MSG( rop == wxCOPY, false, _T("only wxCOPY function supported") );
|
||||||
|
|
||||||
// transform the source DC coords to the device ones
|
// transform the source DC coords to the device ones
|
||||||
xsrc = source->LogicalToDeviceX(xsrc);
|
xsrc = source->LogicalToDeviceX(xsrc);
|
||||||
ysrc = source->LogicalToDeviceY(ysrc);
|
ysrc = source->LogicalToDeviceY(ysrc);
|
||||||
|
|
||||||
/* FIXME_MGL: use the mask origin when drawing transparently */
|
// FIXME_DFB: use the mask origin when drawing transparently
|
||||||
|
wxASSERT_MSG( xsrcMask == -1 && ysrcMask == -1,
|
||||||
|
_T("non-default source mask offset not implemented") );
|
||||||
|
#if 0
|
||||||
if (xsrcMask == -1 && ysrcMask == -1)
|
if (xsrcMask == -1 && ysrcMask == -1)
|
||||||
{
|
{
|
||||||
xsrcMask = xsrc; ysrcMask = ysrc;
|
xsrcMask = xsrc; ysrcMask = ysrc;
|
||||||
@ -671,32 +678,27 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
|||||||
xsrcMask = source->LogicalToDeviceX(xsrcMask);
|
xsrcMask = source->LogicalToDeviceX(xsrcMask);
|
||||||
ysrcMask = source->LogicalToDeviceY(ysrcMask);
|
ysrcMask = source->LogicalToDeviceY(ysrcMask);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CalcBoundingBox(xdest, ydest);
|
wxMemoryDC *sourceAsMemDC = wxDynamicCast(source, wxMemoryDC);
|
||||||
CalcBoundingBox(xdest + width, ydest + height);
|
if ( sourceAsMemDC )
|
||||||
|
|
||||||
/* scale/translate size and position */
|
|
||||||
wxCoord xx = XLOG2DEV(xdest);
|
|
||||||
wxCoord yy = YLOG2DEV(ydest);
|
|
||||||
wxCoord ww = XLOG2DEVREL(width);
|
|
||||||
wxCoord hh = YLOG2DEVREL(height);
|
|
||||||
|
|
||||||
if ( source->m_isMemDC )
|
|
||||||
{
|
{
|
||||||
wxMemoryDC *memDC = (wxMemoryDC*) source;
|
DoDrawSubBitmap(sourceAsMemDC->GetSelectedObject(),
|
||||||
DoDrawSubBitmap(memDC->GetSelectedObject(), xsrc, ysrc, ww, hh,
|
xsrc, ysrc,
|
||||||
xdest, ydest, rop, useMask);
|
width, height,
|
||||||
|
xdest, ydest,
|
||||||
|
rop,
|
||||||
|
useMask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_MGLDC->makeCurrent(); // will go away with MGL6.0
|
return DoBlitFromSurface(source->GetDirectFBSurface(),
|
||||||
m_MGLDC->bitBlt(*source->GetMGLDC(),
|
xsrc, ysrc,
|
||||||
xsrc, ysrc, xsrc + ww, ysrc + hh,
|
width, height,
|
||||||
xx, yy, LogicalFunctionToMGLRop(rop));
|
xdest, ydest);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDC::DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask)
|
void wxDC::DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask)
|
||||||
@ -704,10 +706,10 @@ void wxDC::DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask)
|
|||||||
wxCHECK_RET( Ok(), wxT("invalid dc") );
|
wxCHECK_RET( Ok(), wxT("invalid dc") );
|
||||||
wxCHECK_RET( bmp.Ok(), wxT("invalid bitmap") );
|
wxCHECK_RET( bmp.Ok(), wxT("invalid bitmap") );
|
||||||
|
|
||||||
wxCoord w = bmp.GetWidth();
|
DoDrawSubBitmap(bmp,
|
||||||
wxCoord h = bmp.GetHeight();
|
0, 0, bmp.GetWidth(), bmp.GetHeight(),
|
||||||
|
x, y,
|
||||||
DoDrawSubBitmap(bmp, 0, 0, w, h, x, y, m_logicalFunction, useMask);
|
m_logicalFunction, useMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
|
void wxDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
|
||||||
@ -720,94 +722,65 @@ void wxDC::DoDrawSubBitmap(const wxBitmap &bmp,
|
|||||||
wxCoord x, wxCoord y, wxCoord w, wxCoord h,
|
wxCoord x, wxCoord y, wxCoord w, wxCoord h,
|
||||||
wxCoord destx, wxCoord desty, int rop, bool useMask)
|
wxCoord destx, wxCoord desty, int rop, bool useMask)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
wxCHECK_RET( Ok(), wxT("invalid dc") );
|
wxCHECK_RET( Ok(), wxT("invalid dc") );
|
||||||
wxCHECK_RET( bmp.Ok(), wxT("invalid bitmap") );
|
wxCHECK_RET( bmp.Ok(), wxT("invalid bitmap") );
|
||||||
|
|
||||||
CalcBoundingBox(x, y);
|
// NB: we could also support XOR here (via DSBLIT_XOR)
|
||||||
CalcBoundingBox(x + w, y + h);
|
// and possibly others via SetSrc/DstBlendFunction()
|
||||||
|
wxCHECK_RET( rop == wxCOPY, _T("only wxCOPY function supported") );
|
||||||
wxCoord dx = XLOG2DEV(destx);
|
|
||||||
wxCoord dy = YLOG2DEV(desty);
|
|
||||||
wxCoord dw = XLOG2DEVREL(w);
|
|
||||||
wxCoord dh = YLOG2DEVREL(h);
|
|
||||||
|
|
||||||
m_MGLDC->makeCurrent(); // will go away with MGL6.0
|
|
||||||
|
|
||||||
bool useStretching = ((w != dw) || (h != dh));
|
|
||||||
bool putSection = (w != bmp.GetWidth() || h != bmp.GetHeight());
|
|
||||||
MGL_writeModeType mglRop = (MGL_writeModeType)LogicalFunctionToMGLRop(rop);
|
|
||||||
|
|
||||||
if ( bmp.GetDepth() == 1 )
|
if ( bmp.GetDepth() == 1 )
|
||||||
{
|
{
|
||||||
// Mono bitmaps are handled in special way -- all 1s are drawn in
|
// Mono bitmaps are handled in special way -- all 1s are drawn in
|
||||||
// foreground colours, all 0s in background colour.
|
// foreground colours, all 0s in background colour.
|
||||||
|
wxFAIL_MSG( _T("drawing mono bitmaps not implemented") );
|
||||||
((wxBitmap&)bmp).SetMonoPalette(m_textForegroundColour, m_textBackgroundColour);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( useMask && bmp.GetMask() )
|
if ( useMask && bmp.GetMask() )
|
||||||
{
|
{
|
||||||
// Since MGL does not support masks directly (in MGL, mask is handled
|
// FIXME_DFB: see MGL sources for a way to do it, but it's not directly
|
||||||
// in same way as in wxImage, i.e. there is one "key" color), we
|
// applicable because DirectFB doesn't implement ROPs; OTOH,
|
||||||
// simulate masked bitblt in 6 steps (same as in MSW):
|
// it has blitting modes that can be useful; finally, see
|
||||||
//
|
// DFB's SetSrcBlendFunction() and SetSrcColorKey()
|
||||||
// 1. Create a temporary bitmap and copy the destination area into it.
|
wxFAIL_MSG( _T("drawing bitmaps with masks not implemented") );
|
||||||
// 2. Copy the source area into the temporary bitmap using the
|
return;
|
||||||
// specified logical function.
|
|
||||||
// 3. Set the masked area in the temporary bitmap to BLACK by ANDing
|
|
||||||
// the mask bitmap with the temp bitmap with the foreground colour
|
|
||||||
// set to WHITE and the bg colour set to BLACK.
|
|
||||||
// 4. Set the unmasked area in the destination area to BLACK by
|
|
||||||
// ANDing the mask bitmap with the destination area with the
|
|
||||||
// foreground colour set to BLACK and the background colour set
|
|
||||||
// to WHITE.
|
|
||||||
// 5. OR the temporary bitmap with the destination area.
|
|
||||||
// 6. Delete the temporary bitmap.
|
|
||||||
//
|
|
||||||
// This sequence of operations ensures that the source's transparent
|
|
||||||
// area need not be black, and logical functions are supported.
|
|
||||||
|
|
||||||
wxBitmap *mask = bmp.GetMask()->GetBitmap();
|
|
||||||
|
|
||||||
MGLMemoryDC *temp;
|
|
||||||
|
|
||||||
if ( GetDepth() <= 8 )
|
|
||||||
{
|
|
||||||
temp = new MGLMemoryDC(dw, dh, GetDepth(), NULL);
|
|
||||||
wxDC tempdc;
|
|
||||||
tempdc.SetMGLDC(temp, false);
|
|
||||||
tempdc.SetPalette(m_palette);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pixel_format_t pf;
|
|
||||||
m_MGLDC->getPixelFormat(pf);
|
|
||||||
temp = new MGLMemoryDC(dw, dh, GetDepth(), &pf);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxCHECK_RET( temp->isValid(), wxT("cannot create temporary dc") );
|
|
||||||
|
|
||||||
temp->bitBlt(*m_MGLDC, dx, dy, dx + dw, dy + dh, 0, 0, MGL_REPLACE_MODE);
|
|
||||||
|
|
||||||
DoBitBlt(bmp, temp, x, y, w, h, 0, 0, dw, dh, mglRop,
|
|
||||||
useStretching, putSection);
|
|
||||||
|
|
||||||
mask->SetMonoPalette(wxColour(0,0,0), wxColour(255,255,255));
|
|
||||||
DoBitBlt(*mask, temp, x, y, w, h, 0, 0, dw, dh, MGL_R2_MASKSRC,
|
|
||||||
useStretching, putSection);
|
|
||||||
DoBitBlt(*mask, m_MGLDC, x, y, w, h, dx, dy, dw, dh, MGL_R2_MASKNOTSRC,
|
|
||||||
useStretching, putSection);
|
|
||||||
|
|
||||||
m_MGLDC->bitBlt(*temp, 0, 0, dw, dh, dx, dy, MGL_OR_MODE);
|
|
||||||
|
|
||||||
delete temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DoBlitFromSurface(bmp.GetDirectFBSurface(),
|
||||||
|
x, y,
|
||||||
|
w, h,
|
||||||
|
destx, desty);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxDC::DoBlitFromSurface(const wxIDirectFBSurfacePtr& src,
|
||||||
|
wxCoord srcx, wxCoord srcy,
|
||||||
|
wxCoord w, wxCoord h,
|
||||||
|
wxCoord dstx, wxCoord dsty)
|
||||||
|
{
|
||||||
|
CalcBoundingBox(dstx, dsty);
|
||||||
|
CalcBoundingBox(dstx + w, dsty + h);
|
||||||
|
|
||||||
|
DFBRectangle srcRect = { srcx, srcy, w, h };
|
||||||
|
DFBRectangle dstRect = { XLOG2DEV(dstx), YLOG2DEV(dsty),
|
||||||
|
XLOG2DEVREL(w), YLOG2DEVREL(h) };
|
||||||
|
|
||||||
|
wxIDirectFBSurfacePtr dst(m_surface);
|
||||||
|
|
||||||
|
// FIXME: this will have to be different in useMask case, see above
|
||||||
|
if ( !dst->SetBlittingFlags(DSBLIT_NOFX) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( srcRect.w != dstRect.w || srcRect.h != dstRect.h )
|
||||||
|
{
|
||||||
|
// the bitmap is drawn stretched:
|
||||||
|
dst->StretchBlit(src, &srcRect, &dstRect);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DoBitBlt(bmp, m_MGLDC, x, y, w, h, dx, dy, dw, dh, mglRop,
|
// no stretching, size is preserved:
|
||||||
useStretching, putSection);
|
dst->Blit(src, &srcRect, dstRect.x, dstRect.y);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,8 @@ wxMemoryDC::wxMemoryDC(wxDC *WXUNUSED(dc))
|
|||||||
|
|
||||||
void wxMemoryDC::SelectObject(const wxBitmap& bitmap)
|
void wxMemoryDC::SelectObject(const wxBitmap& bitmap)
|
||||||
{
|
{
|
||||||
|
m_bmp = bitmap;
|
||||||
|
|
||||||
if ( !bitmap.Ok() )
|
if ( !bitmap.Ok() )
|
||||||
{
|
{
|
||||||
// select the bitmap out of the DC
|
// select the bitmap out of the DC
|
||||||
|
Loading…
Reference in New Issue
Block a user